@@ -189,8 +189,8 @@ RuntimeCheckingPtrGroup::RuntimeCheckingPtrGroup(
189
189
}
190
190
191
191
std::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,
194
194
DenseMap<std::pair<const SCEV *, Type *>,
195
195
std::pair<const SCEV *, const SCEV *>> *PointerBounds) {
196
196
std::pair<const SCEV *, const SCEV *> *PtrBoundsPair;
@@ -206,11 +206,31 @@ std::pair<const SCEV *, const SCEV *> llvm::getStartAndEndForAccess(
206
206
const SCEV *ScStart;
207
207
const SCEV *ScEnd;
208
208
209
+ auto &DL = Lp->getHeader ()->getDataLayout ();
210
+ Type *IdxTy = DL.getIndexType (PtrExpr->getType ());
211
+ const SCEV *EltSizeSCEV = SE->getStoreSizeOfExpr (IdxTy, AccessTy);
209
212
if (SE->isLoopInvariant (PtrExpr, Lp)) {
210
213
ScStart = ScEnd = PtrExpr;
211
214
} else if (auto *AR = dyn_cast<SCEVAddRecExpr>(PtrExpr)) {
212
215
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
+ }
214
234
const SCEV *Step = AR->getStepRecurrence (*SE);
215
235
216
236
// For expressions with negative step, the upper bound is ScStart and the
@@ -232,9 +252,6 @@ std::pair<const SCEV *, const SCEV *> llvm::getStartAndEndForAccess(
232
252
assert (SE->isLoopInvariant (ScEnd, Lp) && " ScEnd needs to be invariant" );
233
253
234
254
// 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);
238
255
ScEnd = SE->getAddExpr (ScEnd, EltSizeSCEV);
239
256
240
257
std::pair<const SCEV *, const SCEV *> Res = {ScStart, ScEnd};
@@ -250,9 +267,11 @@ void RuntimePointerChecking::insert(Loop *Lp, Value *Ptr, const SCEV *PtrExpr,
250
267
unsigned DepSetId, unsigned ASId,
251
268
PredicatedScalarEvolution &PSE,
252
269
bool NeedsFreeze) {
253
- const SCEV *MaxBECount = PSE.getSymbolicMaxBackedgeTakenCount ();
270
+ const SCEV *SymbolicMaxBTC = PSE.getSymbolicMaxBackedgeTakenCount ();
271
+ const SCEV *BTC = PSE.getBackedgeTakenCount ();
254
272
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 ());
256
275
assert (!isa<SCEVCouldNotCompute>(ScStart) &&
257
276
!isa<SCEVCouldNotCompute>(ScEnd) &&
258
277
" must be able to compute both start and end expressions" );
@@ -1933,11 +1952,14 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
1933
1952
// required for correctness.
1934
1953
if (SE.isLoopInvariant (Src, InnermostLoop) ||
1935
1954
SE.isLoopInvariant (Sink, InnermostLoop)) {
1936
- const SCEV *MaxBECount = PSE.getSymbolicMaxBackedgeTakenCount ();
1955
+ const SCEV *BTC = PSE.getBackedgeTakenCount ();
1956
+ const SCEV *SymbolicMaxBTC = PSE.getSymbolicMaxBackedgeTakenCount ();
1937
1957
const auto &[SrcStart_, SrcEnd_] = getStartAndEndForAccess (
1938
- InnermostLoop, Src, ATy, MaxBECount, PSE.getSE (), &PointerBounds);
1958
+ InnermostLoop, Src, ATy, BTC, SymbolicMaxBTC, PSE.getSE (),
1959
+ &PointerBounds);
1939
1960
const auto &[SinkStart_, SinkEnd_] = getStartAndEndForAccess (
1940
- InnermostLoop, Sink, BTy, MaxBECount, PSE.getSE (), &PointerBounds);
1961
+ InnermostLoop, Sink, BTy, BTC, SymbolicMaxBTC, PSE.getSE (),
1962
+ &PointerBounds);
1941
1963
if (!isa<SCEVCouldNotCompute>(SrcStart_) &&
1942
1964
!isa<SCEVCouldNotCompute>(SrcEnd_) &&
1943
1965
!isa<SCEVCouldNotCompute>(SinkStart_) &&
0 commit comments