diff options
author | Florian Hahn <flo@fhahn.com> | 2025-09-11 09:08:47 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-11 08:08:47 +0000 |
commit | 70012fda6312ba87bc0bf9009402e0869a816d1f (patch) | |
tree | d1b35e1e3803cbeaca417b2b4386fae03acc33b1 /llvm/lib/Analysis/ScalarEvolution.cpp | |
parent | 0e8f9fce78f8d3971d62bb66fd9813bbe193f99a (diff) | |
download | llvm-70012fda6312ba87bc0bf9009402e0869a816d1f.zip llvm-70012fda6312ba87bc0bf9009402e0869a816d1f.tar.gz llvm-70012fda6312ba87bc0bf9009402e0869a816d1f.tar.bz2 |
[SCEV] Fold (C1 * A /u C2) -> A /u (C2 /u C1), if C2 > C1. (#157656)
If C2 >u C1 and C1 >u 1, fold to A /u (C2 /u C1).
Depends on https://github.com/llvm/llvm-project/pull/157555.
Alive2 Proof: https://alive2.llvm.org/ce/z/BWvQYN
PR: https://github.com/llvm/llvm-project/pull/157656
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 51caffc..ebb8630 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -3217,18 +3217,26 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops, } // 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 C2. + // D is a multiple of C2, and C1 is a multiple of C2. If C2 is a multiple + // of C1, fold to (D /u (C2 /u C1)). const SCEV *D; APInt C1V = LHSC->getAPInt(); - // (C1 * D /u C2) == -1 * -C1 * D /u C2 when C1 != INT_MIN. - if (C1V.isNegative() && !C1V.isMinSignedValue()) + // (C1 * D /u C2) == -1 * -C1 * D /u C2 when C1 != INT_MIN. Don't treat -1 + // as -1 * 1, as it won't enable additional folds. + if (C1V.isNegative() && !C1V.isMinSignedValue() && !C1V.isAllOnes()) C1V = C1V.abs(); const SCEVConstant *C2; if (C1V.isPowerOf2() && match(Ops[1], m_scev_UDiv(m_SCEV(D), m_SCEVConstant(C2))) && - C2->getAPInt().isPowerOf2() && C1V.uge(C2->getAPInt()) && + C2->getAPInt().isPowerOf2() && C1V.logBase2() <= getMinTrailingZeros(D)) { - const SCEV *NewMul = getMulExpr(getUDivExpr(getConstant(C1V), C2), D); + const SCEV *NewMul; + if (C1V.uge(C2->getAPInt())) { + NewMul = getMulExpr(getUDivExpr(getConstant(C1V), C2), D); + } else { + assert(C1V.ugt(1) && "C1 <= 1 should have been folded earlier"); + NewMul = getUDivExpr(D, getUDivExpr(C2, getConstant(C1V))); + } return C1V == LHSC->getAPInt() ? NewMul : getNegativeSCEV(NewMul); } } |