[llvm] [SCEV] Generalize A + zext(-A + B) fold to A + zext(C + X) (PR #209160)
Antonio Frighetto via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 14 06:39:45 PDT 2026
================
@@ -2809,17 +2809,27 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<SCEVUse> &Ops,
}
}
- // Try to push the constant operand into a ZExt: A + zext (-A + B) -> zext
- // (B), if trunc (A) + -A + B does not unsigned-wrap.
- const SCEVAddExpr *InnerAdd;
- if (match(B, m_scev_ZExt(m_scev_Add(InnerAdd)))) {
- const SCEV *NarrowA = getTruncateExpr(A, InnerAdd->getType());
- if (NarrowA == getNegativeSCEV(InnerAdd->getOperand(0)) &&
- getZeroExtendExpr(NarrowA, B->getType()) == A &&
- hasFlags(StrengthenNoWrapFlags(this, scAddExpr, {NarrowA, InnerAdd},
- SCEV::FlagAnyWrap),
+ // Push a negative constant addend out of a ZExt when the inner add is
+ // provably non-negative in the narrow type:
+ //
+ // A + zext(C + X) -> WideAC + zext(X) [WideAC = A + sext(C)]
+ //
+ // Require A to be a constant so that `A + sext(C)` folds into a single wide
+ // constant, actually simplifying the expression.
+ const SCEVAddExpr *Add;
+ if (isa<SCEVConstant>(A) && match(B, m_scev_ZExt(m_scev_Add(Add)))) {
+ const auto *CInner = dyn_cast<SCEVConstant>(Add->getOperand(0));
----------------
antoniofrighetto wrote:
```suggestion
const auto *InnerSC = dyn_cast<SCEVConstant>(Add->getOperand(0));
```
https://github.com/llvm/llvm-project/pull/209160
More information about the llvm-commits
mailing list