[llvm] [LV] Fix random behaviour in LoopVectorizationLegality::isUniform (PR #170463)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 4 02:04:38 PST 2025


================
@@ -517,7 +517,18 @@ class SCEVAddRecForUniformityRewriter
         SE.getMulExpr(Step, SE.getConstant(Ty, StepMultiplier));
     const SCEV *ScaledOffset = SE.getMulExpr(Step, SE.getConstant(Ty, Offset));
     const SCEV *NewStart = SE.getAddExpr(Expr->getStart(), ScaledOffset);
-    return SE.getAddRecExpr(NewStart, NewStep, TheLoop, SCEV::FlagAnyWrap);
+    // We have to be careful when creating new SCEVAddRec expressions because
+    // we may pick up a cached SCEV object with wrap flags already set. This
+    // then leads to random behaviour depending upon which combinations of
+    // offset, StepMultiplier and TheLoop are used. The safest thing we can do
+    // here is to reuse existing wrap flags on the scalar SCEV, since if the
+    // scalar version of the SCEV cannot wrap then the vector version also
+    // cannot. There are situations where the lane of the vector may exceed the
+    // trip count, such as tail-folding. In those cases we shouldn't even be
+    // asking if something is uniform anyway.
+    const SCEV *Res =
+        SE.getAddRecExpr(NewStart, NewStep, TheLoop, Expr->getNoWrapFlags());
----------------
fhahn wrote:

I am not sure it is safe to use the no-wrap flags from the addrec with different start/step here, as the AddRec we create here must be valid for the original scalar loop as well because ScalarEvolution will cache it. Assume we don't vectorize and a later pass constructs the same AddRec and uses the cached variant with potentially incorrect flags.



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


More information about the llvm-commits mailing list