[llvm] [SECV] Try to push the op into ZExt: A + zext (-A + B) -> zext (B) (PR #151227)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 30 02:39:38 PDT 2025


================
@@ -2682,6 +2682,21 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
         return getAddExpr(NewOps, PreservedFlags);
       }
     }
+
+    // Try to push the constant operand into a ZExt: A + zext (-A + B) -> zext
+    // (B), if trunc (A) + -A + B  does not unsigned-wrap.
+    if (auto *ZExt = dyn_cast<SCEVZeroExtendExpr>(Ops[1])) {
+      const SCEV *B = ZExt->getOperand(0);
+      const SCEV *NarrowA = getTruncateExpr(A, B->getType());
+      if (isa<SCEVAddExpr>(B) &&
+          NarrowA == getNegativeSCEV(cast<SCEVAddExpr>(B)->getOperand(0)) &&
+          getZeroExtendExpr(NarrowA, ZExt->getType()) == A &&
+          hasFlags(
+              StrengthenNoWrapFlags(this, scAddExpr, {NarrowA, B}, OrigFlags),
----------------
fhahn wrote:

Yep, it should not pass the original flags. Updated to pass AnyWrapFlags.

This checks adding the truncated first operand and the inner expression of the ZExt does not wrap. Updated proof: https://alive2.llvm.org/ce/z/q7d303

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


More information about the llvm-commits mailing list