[llvm] [InstCombine] Optimize (select %x, op(%x), 0) to op(%x) for operations where op(0) == 0 (PR #147605)

Ryan Buchner via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 10 18:25:52 PDT 2025


================
@@ -913,11 +915,28 @@ static Instruction *foldSelectZeroOrMul(SelectInst &SI, InstCombinerImpl &IC) {
   if (!match(MergedC, m_Zero()) && !match(MergedC, m_Undef()))
     return nullptr;
 
-  auto *FalseValI = cast<Instruction>(FalseVal);
-  auto *FrY = IC.InsertNewInstBefore(new FreezeInst(Y, Y->getName() + ".fr"),
-                                     FalseValI->getIterator());
-  IC.replaceOperand(*FalseValI, FalseValI->getOperand(0) == Y ? 0 : 1, FrY);
-  return IC.replaceInstUsesWith(SI, FalseValI);
+  if (match(FalseVal, m_c_Mul(m_Specific(X), m_Value(Y))) ||
+      match(FalseVal, m_c_And(m_Specific(X), m_Value(Y))) ||
+      match(FalseVal, m_Shl(m_Specific(X), m_Value(Y))) ||
----------------
bababuck wrote:

I am going to leave the shift's out from this MR for the following reason. For shift operations, if the inputs are guaranteed not to be poison, whether or not the operation `isGuaranteedNotToBePoison` boils down to the `shamt`, and a function call to `static bool shiftAmountKnownInRange(const Value *ShiftAmount)`, which checks if the `shamt` is a Constant smaller than the bit-width.

However, there is an existing transformation in `InstCombine` that handles the cases for which the `shamt` is a constant, so it seems redundant to include it here.

A separate note, if we could get `static bool shiftAmountKnownInRange(const Value *ShiftAmount)` access to information about Value's ranges (i.e. range(i64 0 10)) it would be effective in more situations.

https://github.com/llvm/llvm-project/pull/147605


More information about the llvm-commits mailing list