[llvm] [InstCombine] Fold (X == 0 ? Y : 0) | X to X == 0 ? Y : X (PR #138373)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Sun May 4 13:51:12 PDT 2025
================
@@ -1714,6 +1714,35 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI,
}
}
+ // Optimize patterns where an OR operation combines a select-based zero check
+ // with its condition value. This handles both scalar and vector types.
+ //
+ // Given:
+ // (X == 0 ? Y : 0) | X --> X == 0 ? Y : X
+ // X | (X == 0 ? Y : 0) --> X == 0 ? Y : X
+ //
+ // Also handles cases where X might be wrapped in zero/sign extensions.
+ if (Op.getOpcode() == Instruction::Or) {
+ // Check both operand orders to handle commutative OR
+ // The other operand in the OR operation (potentially X or extended X)
+ Value *Other = Op.getOperand(0) == SI ? Op.getOperand(1) : Op.getOperand(0);
+
+ CmpPredicate Pred;
+ Value *X, *Y;
+ // Attempt to match the select pattern:
+ // select(icmp eq X, 0), Y, 0
+ // Where X might be:
+ // - Original value
+ // - Zero extended value (zext)
+ // - Sign extended value (sext)
+ if (match(SI, m_Select(m_ICmp(Pred, m_Value(X), m_Zero()), m_Value(Y),
+ m_Zero())) &&
+ Pred == ICmpInst::ICMP_EQ &&
+ match(Other, m_ZExtOrSExtOrSelf(m_Specific(X)))) {
+ return SelectInst::Create(SI->getCondition(), Y, Other);
+ }
+ }
----------------
nikic wrote:
If we ignore the sext/zext case, is this additional code even needed? The reason I suggested FoldOpIntoSelect is that the code in https://github.com/llvm/llvm-project/blob/5f32b8fc754f3df1ae0a92ef783b66969738404f/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp#L1658-L1678 should already handle this pattern automatically.
https://github.com/llvm/llvm-project/pull/138373
More information about the llvm-commits
mailing list