@@ -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