[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