Skip to content

Commit b10c3f0

Browse files
committed
add the fold support in FoldOpIntoSelect
1 parent 6fdcdea commit b10c3f0

File tree

2 files changed

+39
-38
lines changed

2 files changed

+39
-38
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 8 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3575,41 +3575,6 @@ static Value *foldOrOfInversions(BinaryOperator &I,
35753575
return nullptr;
35763576
}
35773577

3578-
// Optimize patterns where an OR operation combines a select-based zero check
3579-
// with its condition value. This handles both scalar and vector types.
3580-
//
3581-
// Given:
3582-
// (X == 0 ? Y : 0) | X --> X == 0 ? Y : X
3583-
// X | (X == 0 ? Y : 0) --> X == 0 ? Y : X
3584-
//
3585-
// Also handles cases where X might be wrapped in zero/sign extensions.
3586-
static Instruction *foldOrOfSelectZero(BinaryOperator &BO, Value *Op0,
3587-
Value *Op1) {
3588-
CmpPredicate Pred;
3589-
Value *X, *Y;
3590-
3591-
// Check both operand orders to handle commutative OR
3592-
for (Value *SelVal : {Op0, Op1}) {
3593-
// The other operand in the OR operation (potentially X or extended X)
3594-
Value *Other = (SelVal == Op0) ? Op1 : Op0;
3595-
3596-
// Attempt to match the select pattern:
3597-
// select(icmp eq X, 0), Y, 0
3598-
// Where X might be:
3599-
// - Original value
3600-
// - Zero extended value (zext)
3601-
// - Sign extended value (sext)
3602-
if (match(SelVal, m_Select(m_c_ICmp(Pred, m_Value(X), m_Zero()), m_Value(Y),
3603-
m_Zero())) &&
3604-
Pred == ICmpInst::ICMP_EQ &&
3605-
match(Other, m_ZExtOrSExtOrSelf(m_Specific(X)))) {
3606-
return SelectInst::Create(cast<SelectInst>(SelVal)->getCondition(), Y,
3607-
Other);
3608-
}
3609-
}
3610-
return nullptr;
3611-
}
3612-
36133578
// FIXME: We use commutative matchers (m_c_*) for some, but not all, matches
36143579
// here. We should standardize that construct where it is needed or choose some
36153580
// other way to ensure that commutated variants of patterns are not missed.
@@ -3692,11 +3657,15 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
36923657
/*NSW=*/true, /*NUW=*/true))
36933658
return R;
36943659
}
3695-
3660+
36963661
// (X == 0 ? Y : 0) | X -> X == 0 ? Y : X
36973662
// X | (X == 0 ? Y : 0) -> X == 0 ? Y : X
3698-
if (Instruction *R = foldOrOfSelectZero(I, Op0, Op1))
3699-
return R;
3663+
for (Value *Op : {Op0, Op1}) {
3664+
if (auto *SI = dyn_cast<SelectInst>(Op)) {
3665+
if (auto *R = FoldOpIntoSelect(I, SI, /* FoldWithMultiUse */ false))
3666+
return R;
3667+
}
3668+
}
37003669

37013670
Value *X, *Y;
37023671
const APInt *CV;
@@ -5078,3 +5047,4 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
50785047

50795048
return nullptr;
50805049
}
5050+

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,6 +1714,36 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI,
17141714
}
17151715
}
17161716

1717+
// Optimize patterns where an OR operation combines a select-based zero check
1718+
// with its condition value. This handles both scalar and vector types.
1719+
//
1720+
// Given:
1721+
// (X == 0 ? Y : 0) | X --> X == 0 ? Y : X
1722+
// X | (X == 0 ? Y : 0) --> X == 0 ? Y : X
1723+
//
1724+
// Also handles cases where X might be wrapped in zero/sign extensions.
1725+
if (Op.getOpcode() == Instruction::Or) {
1726+
// Check both operand orders to handle commutative OR
1727+
// The other operand in the OR operation (potentially X or extended X)
1728+
Value *Other = Op.getOperand(0) == SI ? Op.getOperand(1) : Op.getOperand(0);
1729+
1730+
CmpPredicate Pred;
1731+
Value *X, *Y;
1732+
// Attempt to match the select pattern:
1733+
// select(icmp eq X, 0), Y, 0
1734+
// Where X might be:
1735+
// - Original value
1736+
// - Zero extended value (zext)
1737+
// - Sign extended value (sext)
1738+
if (match(SI, m_Select(m_ICmp(Pred, m_Value(X), m_Zero()), m_Value(Y),
1739+
m_Zero())) &&
1740+
Pred == ICmpInst::ICMP_EQ &&
1741+
match(Other, m_ZExtOrSExtOrSelf(m_Specific(X)))) {
1742+
return SelectInst::Create(SI->getCondition(), Y,
1743+
Other);
1744+
}
1745+
}
1746+
17171747
// Make sure that one of the select arms folds successfully.
17181748
Value *NewTV = simplifyOperationIntoSelectOperand(Op, SI, /*IsTrueArm=*/true);
17191749
Value *NewFV =
@@ -5791,3 +5821,4 @@ void llvm::initializeInstCombine(PassRegistry &Registry) {
57915821
FunctionPass *llvm::createInstructionCombiningPass() {
57925822
return new InstructionCombiningPass();
57935823
}
5824+

0 commit comments

Comments
 (0)