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

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 9 22:58:14 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))) ||
----------------
dtcxzyw wrote:

> If I wanted to perform this transformation on the shift operators (shl, ashr, lshr), should that get done during target specific lowering (i.e. RISCV sll instruction uses modulo bitwidth for shamt)?

You can check if `Y` is never poison with `isGuaranteedNotTobePoison`.

and/mul: valid with freeze(Y) if `Y` may be poison
shl/lshr/ashr: valid if `Y` cannot be poison
udiv/sdiv/urem/srem: always valid without freeze


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


More information about the llvm-commits mailing list