[llvm] [SCEV] Generalize (C * A /u C) -> A fold to (C1 * A /u C2) -> C1/C2 * A. (PR #157159)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 8 08:16:29 PDT 2025
================
@@ -3216,13 +3216,16 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
};
}
- // Try to fold (C * D /u C) -> D, if C is a power-of-2 and D is a multiple
- // of C.
+ // Try to fold (C1 * D /u C2) -> C1/C2 * D, if C1 and C2 are powers-of-2,
+ // D is a multiple of C2, and C1 is a multiple of C1.
const SCEV *D;
- if (match(Ops[1], m_scev_UDiv(m_SCEV(D), m_scev_Specific(LHSC))) &&
- LHSC->getAPInt().isPowerOf2() &&
- LHSC->getAPInt().logBase2() <= getMinTrailingZeros(D)) {
- return D;
+ const SCEVConstant *C2;
+ if (LHSC->getAPInt().isPowerOf2() &&
+ match(Ops[1], m_scev_UDiv(m_SCEV(D), m_SCEVConstant(C2))) &&
+ C2->getAPInt().isPowerOf2() &&
+ getMinTrailingZeros(LHSC) >= getMinTrailingZeros(C2) &&
----------------
fhahn wrote:
Yep, but probably better to do this separately, as when doing so bc0933395459b39879ad7ed6527a741d1ca515a7 it appears there's another fold missing to avoid regressions:
`(-2 * ((zext i32 %start to i64) /u 4))<nsw> -> (-1 * ((zext i32 %start to i64) /u 2))<nsw> `
https://github.com/llvm/llvm-project/pull/157159
More information about the llvm-commits
mailing list