[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