[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 23:00:26 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))) ||
+ match(FalseVal, m_AShr(m_Specific(X), m_Value(Y))) ||
+ match(FalseVal, m_LShr(m_Specific(X), m_Value(Y))) ||
+ match(FalseVal, m_FShl(m_Specific(X), m_Specific(X), m_Value(Y))) ||
+ match(FalseVal, m_FShr(m_Specific(X), m_Specific(X), m_Value(Y))) ||
+ match(FalseVal, m_SDiv(m_Specific(X), m_Value(Y))) ||
+ match(FalseVal, m_UDiv(m_Specific(X), m_Value(Y))) ||
----------------
dtcxzyw wrote:
> Should `sdiv` and `udiv` should be removed as well since they can create `undef` in the case of the denominator being `0`? My understanding is that `0 / freeze(y)` would be more poisonous than `0` in that case when `freeze(y)` is `0`.
It is safe, even without inserting freeze. If `Y` is poison, it means `div/rem X, Y` triggers immediate UB before the select. Therefore, `Y` cannot be poison.
https://github.com/llvm/llvm-project/pull/147605
More information about the llvm-commits
mailing list