[llvm] [Analysis] Optimise mul(const, (udiv %n, const)) during SCEV expansion (PR #212769)

David Sherwood via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 30 01:08:09 PDT 2026


================
@@ -599,6 +599,27 @@ Value *SCEVExpander::visitAddExpr(SCEVUseT<const SCEVAddExpr *> S) {
 Value *SCEVExpander::visitMulExpr(SCEVUseT<const SCEVMulExpr *> S) {
   Type *Ty = S->getType();
 
+  // Specializations for 2-operand cases.
+  if (S->getNumOperands() == 2) {
+    const SCEVConstant *MulC;
+    const SCEV *Val;
+    // mul(PowerOf2C, (udiv X, PowerOf2C)) == (X >> C) << C
----------------
david-arm wrote:

So visitUDiv does already convert `udiv(x, PowerOf2C)` -> `lshr(x, C)`. Looking at the inverse pattern mentioned above I'm not sure if it's worth it, since instcombine introduces two instructions:

```
  // Transform  (x << y) >> y  to  x & (-1 >> y)
  if (match(Op0, m_OneUse(m_Shl(m_Value(X), m_Specific(Op1))))) {
    Constant *AllOnes = ConstantInt::getAllOnesValue(Ty);
    Value *Mask = Builder.CreateLShr(AllOnes, Op1);
    return BinaryOperator::CreateAnd(Mask, X);
  }
```

i.e. replacing 2 insns with 2 different insns. Without the ability to check use counts I'm not sure if it's worth it, unless we know the lshr ends up as a constant. Also, not one instance of this is seen in the LLVM test suite.

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


More information about the llvm-commits mailing list