[llvm] [SCEV] Fix NSW flag propagation in getGEPExpr, getMulExpr, and getAddExpr (PR #155145)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 24 00:56:45 PDT 2025


================
@@ -3760,6 +3798,31 @@ ScalarEvolution::getGEPExpr(GEPOperator *GEP,
   if (NW.hasNoUnsignedWrap())
     OffsetWrap = setFlags(OffsetWrap, SCEV::FlagNUW);
 
+  // Inherit flags from index expressions when GEP has no explicit flags.
+  if (OffsetWrap == SCEV::FlagAnyWrap) {
+    // Check if all index expressions have compatible no-wrap flags
+    bool AllHaveNSW = true, AllHaveNUW = true;
+    for (const SCEV *IndexExpr : IndexExprs) {
+      if (auto *AR = dyn_cast<SCEVAddRecExpr>(IndexExpr)) {
+        if (!AR->hasNoSignedWrap())
+          AllHaveNSW = false;
+        if (!AR->hasNoUnsignedWrap())
+          AllHaveNUW = false;
+      } else {
+        // Be conservative for non-AddRec expressions.
+        AllHaveNSW = false;
+        AllHaveNUW = false;
+        break;
+      }
+    }
+    // Inherit NSW if all have NSW.
+    if (AllHaveNSW)
+      OffsetWrap = setFlags(OffsetWrap, SCEV::FlagNSW);
+    // Inherit NUW if all have NUW.
+    if (AllHaveNUW)
+      OffsetWrap = setFlags(OffsetWrap, SCEV::FlagNUW);
+  }
----------------
nikic wrote:

I don't get what you're doing here. E.g. if you have `getelementptr i32, ptr %p, i64 %idx` and `%idx` is nowrap, then there is no reason to believe that `4 * %idx` is also nowrap, which is what the OffsetWrap is about.

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


More information about the llvm-commits mailing list