[llvm] [SCEV] Try to push op into ZExt: C * zext (A + B) -> zext (A*C + B*C) (PR #155300)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 26 01:27:44 PDT 2025
================
@@ -3199,6 +3199,22 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
AddRec->getNoWrapFlags(FlagsMask));
}
}
+
+ // Try to push the constant operand into a ZExt: C + zext (A + B) ->
+ // zext (C*A + C*B) if trunc (C) * (A + B) does not unsigned-wrap.
+ const SCEVAddExpr *InnerAdd;
+ if (match(Ops[1], m_scev_ZExt(m_scev_Add(InnerAdd)))) {
+ const SCEV *NarrowC = getTruncateExpr(LHSC, InnerAdd->getType());
+ if (isa<SCEVConstant>(InnerAdd->getOperand(0)) &&
+ getZeroExtendExpr(NarrowC, Ops[1]->getType()) == LHSC &&
+ hasFlags(StrengthenNoWrapFlags(this, scMulExpr, {NarrowC, InnerAdd},
+ SCEV::FlagAnyWrap),
+ SCEV::FlagNUW)) {
+ auto *Res =
+ getMulExpr(NarrowC, InnerAdd, SCEV::FlagAnyWrap, Depth + 1);
----------------
nikic wrote:
May as well pass NUW here, as you already proved it?
https://github.com/llvm/llvm-project/pull/155300
More information about the llvm-commits
mailing list