[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