@@ -189,8 +189,8 @@ RuntimeCheckingPtrGroup::RuntimeCheckingPtrGroup(
189189}
190190
191191std::pair<const SCEV *, const SCEV *> llvm::getStartAndEndForAccess (
192- const Loop *Lp, const SCEV *PtrExpr, Type *AccessTy, const SCEV *MaxBECount ,
193- ScalarEvolution *SE,
192+ const Loop *Lp, const SCEV *PtrExpr, Type *AccessTy, const SCEV *BTC ,
193+ const SCEV *SymbolicMaxBTC, ScalarEvolution *SE,
194194 DenseMap<std::pair<const SCEV *, Type *>,
195195 std::pair<const SCEV *, const SCEV *>> *PointerBounds) {
196196 std::pair<const SCEV *, const SCEV *> *PtrBoundsPair;
@@ -206,11 +206,31 @@ std::pair<const SCEV *, const SCEV *> llvm::getStartAndEndForAccess(
206206 const SCEV *ScStart;
207207 const SCEV *ScEnd;
208208
209+ auto &DL = Lp->getHeader ()->getDataLayout ();
210+ Type *IdxTy = DL.getIndexType (PtrExpr->getType ());
211+ const SCEV *EltSizeSCEV = SE->getStoreSizeOfExpr (IdxTy, AccessTy);
209212 if (SE->isLoopInvariant (PtrExpr, Lp)) {
210213 ScStart = ScEnd = PtrExpr;
211214 } else if (auto *AR = dyn_cast<SCEVAddRecExpr>(PtrExpr)) {
212215 ScStart = AR->getStart ();
213- ScEnd = AR->evaluateAtIteration (MaxBECount, *SE);
216+ if (!isa<SCEVCouldNotCompute>(BTC))
217+ // Evaluating AR at an exact BTC is safe: LAA separately checks that
218+ // accesses cannot wrap in the loop. If evaluating AR at BTC wraps, then
219+ // the loop either triggers UB when executing a memory access with a
220+ // poison pointer or the wrapping/poisoned pointer is not used.
221+ ScEnd = AR->evaluateAtIteration (BTC, *SE);
222+ else {
223+ // Evaluating AR at MaxBTC may wrap and create an expression that is less
224+ // than the start of the AddRec due to wrapping (for example consider
225+ // MaxBTC = -2). If that's the case, set ScEnd to -(EltSize + 1). ScEnd
226+ // will get incremented by EltSize before returning, so this effectively
227+ // sets ScEnd to unsigned max. Note that LAA separately checks that
228+ // accesses cannot not wrap, so unsigned max represents an upper bound.
229+ ScEnd = AR->evaluateAtIteration (SymbolicMaxBTC, *SE);
230+ if (!SE->isKnownNonNegative (SE->getMinusSCEV (ScEnd, ScStart)))
231+ ScEnd = SE->getNegativeSCEV (
232+ SE->getAddExpr (EltSizeSCEV, SE->getOne (EltSizeSCEV->getType ())));
233+ }
214234 const SCEV *Step = AR->getStepRecurrence (*SE);
215235
216236 // For expressions with negative step, the upper bound is ScStart and the
@@ -232,9 +252,6 @@ std::pair<const SCEV *, const SCEV *> llvm::getStartAndEndForAccess(
232252 assert (SE->isLoopInvariant (ScEnd, Lp) && " ScEnd needs to be invariant" );
233253
234254 // Add the size of the pointed element to ScEnd.
235- auto &DL = Lp->getHeader ()->getDataLayout ();
236- Type *IdxTy = DL.getIndexType (PtrExpr->getType ());
237- const SCEV *EltSizeSCEV = SE->getStoreSizeOfExpr (IdxTy, AccessTy);
238255 ScEnd = SE->getAddExpr (ScEnd, EltSizeSCEV);
239256
240257 std::pair<const SCEV *, const SCEV *> Res = {ScStart, ScEnd};
@@ -250,9 +267,11 @@ void RuntimePointerChecking::insert(Loop *Lp, Value *Ptr, const SCEV *PtrExpr,
250267 unsigned DepSetId, unsigned ASId,
251268 PredicatedScalarEvolution &PSE,
252269 bool NeedsFreeze) {
253- const SCEV *MaxBECount = PSE.getSymbolicMaxBackedgeTakenCount ();
270+ const SCEV *SymbolicMaxBTC = PSE.getSymbolicMaxBackedgeTakenCount ();
271+ const SCEV *BTC = PSE.getBackedgeTakenCount ();
254272 const auto &[ScStart, ScEnd] = getStartAndEndForAccess (
255- Lp, PtrExpr, AccessTy, MaxBECount, PSE.getSE (), &DC.getPointerBounds ());
273+ Lp, PtrExpr, AccessTy, BTC, SymbolicMaxBTC, PSE.getSE (),
274+ &DC.getPointerBounds ());
256275 assert (!isa<SCEVCouldNotCompute>(ScStart) &&
257276 !isa<SCEVCouldNotCompute>(ScEnd) &&
258277 " must be able to compute both start and end expressions" );
@@ -1933,11 +1952,14 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
19331952 // required for correctness.
19341953 if (SE.isLoopInvariant (Src, InnermostLoop) ||
19351954 SE.isLoopInvariant (Sink, InnermostLoop)) {
1936- const SCEV *MaxBECount = PSE.getSymbolicMaxBackedgeTakenCount ();
1955+ const SCEV *BTC = PSE.getBackedgeTakenCount ();
1956+ const SCEV *SymbolicMaxBTC = PSE.getSymbolicMaxBackedgeTakenCount ();
19371957 const auto &[SrcStart_, SrcEnd_] = getStartAndEndForAccess (
1938- InnermostLoop, Src, ATy, MaxBECount, PSE.getSE (), &PointerBounds);
1958+ InnermostLoop, Src, ATy, BTC, SymbolicMaxBTC, PSE.getSE (),
1959+ &PointerBounds);
19391960 const auto &[SinkStart_, SinkEnd_] = getStartAndEndForAccess (
1940- InnermostLoop, Sink, BTy, MaxBECount, PSE.getSE (), &PointerBounds);
1961+ InnermostLoop, Sink, BTy, BTC, SymbolicMaxBTC, PSE.getSE (),
1962+ &PointerBounds);
19411963 if (!isa<SCEVCouldNotCompute>(SrcStart_) &&
19421964 !isa<SCEVCouldNotCompute>(SrcEnd_) &&
19431965 !isa<SCEVCouldNotCompute>(SinkStart_) &&
0 commit comments