@@ -855,16 +855,61 @@ getStrideFromAddRec(const SCEVAddRecExpr *AR, const Loop *Lp, Type *AccessTy,
855855 return Stride;
856856}
857857
858+ static bool isNoWrapAddRec (Value *Ptr, const SCEVAddRecExpr *AR,
859+ PredicatedScalarEvolution &PSE, const Loop *L);
860+
858861// / Check whether a pointer address cannot wrap.
859862static bool isNoWrap (PredicatedScalarEvolution &PSE,
860863 const DenseMap<Value *, const SCEV *> &Strides, Value *Ptr,
861- Type *AccessTy, Loop *L, bool Assume) {
862- const SCEV *PtrScev = PSE.getSCEV (Ptr);
864+ Type *AccessTy, const Loop *L, bool Assume,
865+ std::optional<int64_t > Stride = std::nullopt ) {
866+ const SCEV *PtrScev = replaceSymbolicStrideSCEV (PSE, Strides, Ptr);
863867 if (PSE.getSE ()->isLoopInvariant (PtrScev, L))
864868 return true ;
865869
866- return getPtrStride (PSE, AccessTy, Ptr, L, Strides, Assume).has_value () ||
867- PSE.hasNoOverflow (Ptr, SCEVWrapPredicate::IncrementNUSW);
870+ const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PtrScev);
871+ if (!AR) {
872+ if (!Assume)
873+ return false ;
874+ AR = PSE.getAsAddRec (Ptr);
875+ }
876+
877+ // The address calculation must not wrap. Otherwise, a dependence could be
878+ // inverted.
879+ if (isNoWrapAddRec (Ptr, AR, PSE, L))
880+ return true ;
881+
882+ // An nusw getelementptr that is an AddRec cannot wrap. If it would wrap,
883+ // the distance between the previously accessed location and the wrapped
884+ // location will be larger than half the pointer index type space. In that
885+ // case, the GEP would be poison and any memory access dependent on it would
886+ // be immediate UB when executed.
887+ if (auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
888+ GEP && GEP->hasNoUnsignedSignedWrap ())
889+ return true ;
890+
891+ if (!Stride)
892+ Stride = getStrideFromAddRec (AR, L, AccessTy, Ptr, PSE);
893+ if (Stride) {
894+ // If the null pointer is undefined, then a access sequence which would
895+ // otherwise access it can be assumed not to unsigned wrap. Note that this
896+ // assumes the object in memory is aligned to the natural alignment.
897+ unsigned AddrSpace = AR->getType ()->getPointerAddressSpace ();
898+ if (!NullPointerIsDefined (L->getHeader ()->getParent (), AddrSpace) &&
899+ (Stride == 1 || Stride == -1 ))
900+ return true ;
901+ }
902+
903+ if (Assume) {
904+ PSE.setNoOverflow (Ptr, SCEVWrapPredicate::IncrementNUSW);
905+ LLVM_DEBUG (dbgs () << " LAA: Pointer may wrap:\n "
906+ << " LAA: Pointer: " << *Ptr << " \n "
907+ << " LAA: SCEV: " << *AR << " \n "
908+ << " LAA: Added an overflow assumption\n " );
909+ return true ;
910+ }
911+
912+ return PSE.hasNoOverflow (Ptr, SCEVWrapPredicate::IncrementNUSW);
868913}
869914
870915static void visitPointers (Value *StartPtr, const Loop &InnermostLoop,
@@ -1505,36 +1550,9 @@ llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr,
15051550 if (!ShouldCheckWrap || !Stride)
15061551 return Stride;
15071552
1508- // The address calculation must not wrap. Otherwise, a dependence could be
1509- // inverted.
1510- if (isNoWrapAddRec (Ptr, AR, PSE, Lp))
1511- return Stride;
1512-
1513- // An nusw getelementptr that is an AddRec cannot wrap. If it would wrap,
1514- // the distance between the previously accessed location and the wrapped
1515- // location will be larger than half the pointer index type space. In that
1516- // case, the GEP would be poison and any memory access dependent on it would
1517- // be immediate UB when executed.
1518- if (auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
1519- GEP && GEP->hasNoUnsignedSignedWrap ())
1520- return Stride;
1521-
1522- // If the null pointer is undefined, then a access sequence which would
1523- // otherwise access it can be assumed not to unsigned wrap. Note that this
1524- // assumes the object in memory is aligned to the natural alignment.
1525- unsigned AddrSpace = Ty->getPointerAddressSpace ();
1526- if (!NullPointerIsDefined (Lp->getHeader ()->getParent (), AddrSpace) &&
1527- (Stride == 1 || Stride == -1 ))
1553+ if (isNoWrap (PSE, StridesMap, Ptr, AccessTy, Lp, Assume, Stride))
15281554 return Stride;
15291555
1530- if (Assume) {
1531- PSE.setNoOverflow (Ptr, SCEVWrapPredicate::IncrementNUSW);
1532- LLVM_DEBUG (dbgs () << " LAA: Pointer may wrap:\n "
1533- << " LAA: Pointer: " << *Ptr << " \n "
1534- << " LAA: SCEV: " << *AR << " \n "
1535- << " LAA: Added an overflow assumption\n " );
1536- return Stride;
1537- }
15381556 LLVM_DEBUG (
15391557 dbgs () << " LAA: Bad stride - Pointer may wrap in the address space "
15401558 << *Ptr << " SCEV: " << *AR << " \n " );
0 commit comments