diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp index 7d6dbd51a404d..23bfd9989469a 100644 --- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -793,7 +793,8 @@ class AccessAnalysis { } // end anonymous namespace -/// Try to compute the stride for \p AR. Used by getPtrStride. +/// Try to compute a constant stride for \p AR. Used by getPtrStride and +/// isNoWrap. static std::optional getStrideFromAddRec(const SCEVAddRecExpr *AR, const Loop *Lp, Type *AccessTy, Value *Ptr, PredicatedScalarEvolution &PSE) { @@ -835,16 +836,24 @@ getStrideFromAddRec(const SCEVAddRecExpr *AR, const Loop *Lp, Type *AccessTy, return Stride; } -static bool isNoWrapAddRec(Value *Ptr, const SCEVAddRecExpr *AR, - PredicatedScalarEvolution &PSE, const Loop *L); +static bool isNoWrapGEP(Value *Ptr, PredicatedScalarEvolution &PSE, + const Loop *L); -/// Check whether a pointer address cannot wrap. +/// Check whether \p AR is a non-wrapping AddRec, or if \p Ptr is a non-wrapping +/// GEP. static bool isNoWrap(PredicatedScalarEvolution &PSE, const SCEVAddRecExpr *AR, Value *Ptr, Type *AccessTy, const Loop *L, bool Assume, std::optional Stride = std::nullopt) { + // FIXME: This should probably only return true for NUW. + if (AR->getNoWrapFlags(SCEV::NoWrapMask)) + return true; + + if (PSE.hasNoOverflow(Ptr, SCEVWrapPredicate::IncrementNUSW)) + return true; + // The address calculation must not wrap. Otherwise, a dependence could be // inverted. - if (isNoWrapAddRec(Ptr, AR, PSE, L)) + if (isNoWrapGEP(Ptr, PSE, L)) return true; // An nusw getelementptr that is an AddRec cannot wrap. If it would wrap, @@ -1445,18 +1454,9 @@ void AccessAnalysis::processMemAccesses() { } } -/// Return true if an AddRec pointer \p Ptr is unsigned non-wrapping, -/// i.e. monotonically increasing/decreasing. -static bool isNoWrapAddRec(Value *Ptr, const SCEVAddRecExpr *AR, - PredicatedScalarEvolution &PSE, const Loop *L) { - - // FIXME: This should probably only return true for NUW. - if (AR->getNoWrapFlags(SCEV::NoWrapMask)) - return true; - - if (PSE.hasNoOverflow(Ptr, SCEVWrapPredicate::IncrementNUSW)) - return true; - +/// Check whether \p Ptr is non-wrapping GEP. +static bool isNoWrapGEP(Value *Ptr, PredicatedScalarEvolution &PSE, + const Loop *L) { // Scalar evolution does not propagate the non-wrapping flags to values that // are derived from a non-wrapping induction variable because non-wrapping // could be flow-sensitive.