@@ -1231,48 +1231,40 @@ static void findForkedSCEVs(
12311231 }
12321232}
12331233
1234- static SmallVector<PointerIntPair<const SCEV *, 1 , bool >>
1235- findForkedPointer (PredicatedScalarEvolution &PSE,
1236- const DenseMap<Value *, const SCEV *> &StridesMap, Value *Ptr,
1237- const Loop *L) {
1238- ScalarEvolution *SE = PSE.getSE ();
1239- assert (SE->isSCEVable (Ptr->getType ()) && " Value is not SCEVable!" );
1240- SmallVector<PointerIntPair<const SCEV *, 1 , bool >> Scevs;
1241- findForkedSCEVs (SE, L, Ptr, Scevs, MaxForkedSCEVDepth);
1242-
1243- // For now, we will only accept a forked pointer with two possible SCEVs
1244- // that are either SCEVAddRecExprs or loop invariant.
1245- if (Scevs.size () == 2 &&
1246- (isa<SCEVAddRecExpr>(get<0 >(Scevs[0 ])) ||
1247- SE->isLoopInvariant (get<0 >(Scevs[0 ]), L)) &&
1248- (isa<SCEVAddRecExpr>(get<0 >(Scevs[1 ])) ||
1249- SE->isLoopInvariant (get<0 >(Scevs[1 ]), L))) {
1250- LLVM_DEBUG (dbgs () << " LAA: Found forked pointer: " << *Ptr << " \n " );
1251- LLVM_DEBUG (dbgs () << " \t (1) " << *get<0 >(Scevs[0 ]) << " \n " );
1252- LLVM_DEBUG (dbgs () << " \t (2) " << *get<0 >(Scevs[1 ]) << " \n " );
1253- return Scevs;
1254- }
1255-
1256- return {{replaceSymbolicStrideSCEV (PSE, StridesMap, Ptr), false }};
1257- }
1258-
12591234bool AccessAnalysis::createCheckForAccess (
12601235 RuntimePointerChecking &RtCheck, MemAccessInfo Access, Type *AccessTy,
12611236 const DenseMap<Value *, const SCEV *> &StridesMap,
12621237 DenseMap<Value *, unsigned > &DepSetId, Loop *TheLoop,
12631238 unsigned &RunningDepId, unsigned ASId, bool Assume) {
12641239 Value *Ptr = Access.getPointer ();
1240+ ScalarEvolution *SE = PSE.getSE ();
1241+ assert (SE->isSCEVable (Ptr->getType ()) && " Value is not SCEVable!" );
12651242
1266- SmallVector<PointerIntPair<const SCEV *, 1 , bool >> TranslatedPtrs =
1267- findForkedPointer (PSE, StridesMap, Ptr, TheLoop);
1268- assert (!TranslatedPtrs.empty () && " must have some translated pointers" );
1243+ SmallVector<PointerIntPair<const SCEV *, 1 , bool >> RTCheckPtrs;
1244+ findForkedSCEVs (SE, TheLoop, Ptr, RTCheckPtrs, MaxForkedSCEVDepth);
1245+ assert (!RTCheckPtrs.empty () &&
1246+ " Must have some runtime-check pointer candidates" );
1247+
1248+ // RTCheckPtrs must have size 2 if there are forked pointers. Otherwise, there
1249+ // are no forked pointers; replaceSymbolicStridesSCEV in this case.
1250+ auto IsLoopInvariantOrAR =
1251+ [&SE, &TheLoop](const PointerIntPair<const SCEV *, 1 , bool > &P) {
1252+ return SE->isLoopInvariant (P.getPointer (), TheLoop) ||
1253+ isa<SCEVAddRecExpr>(P.getPointer ());
1254+ };
1255+ if (RTCheckPtrs.size () == 2 && all_of (RTCheckPtrs, IsLoopInvariantOrAR)) {
1256+ LLVM_DEBUG (dbgs () << " LAA: Found forked pointer: " << *Ptr << " \n " ;
1257+ for (const auto &[Idx, Q] : enumerate(RTCheckPtrs)) dbgs ()
1258+ << " \t (" << Idx << " ) " << *Q.getPointer () << " \n " );
1259+ } else {
1260+ RTCheckPtrs = {{replaceSymbolicStrideSCEV (PSE, StridesMap, Ptr), false }};
1261+ }
12691262
12701263 // / Check whether all pointers can participate in a runtime bounds check. They
1271- // / must either be invariant or AddRecs. If ShouldCheckWrap is true, they also
1272- // / must not wrap.
1273- for (auto &P : TranslatedPtrs) {
1264+ // / must either be invariant or non-wrapping affine AddRecs.
1265+ for (auto &P : RTCheckPtrs) {
12741266 // The bounds for loop-invariant pointer is trivial.
1275- if (PSE. getSE () ->isLoopInvariant (P.getPointer (), TheLoop))
1267+ if (SE ->isLoopInvariant (P.getPointer (), TheLoop))
12761268 continue ;
12771269
12781270 const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(P.getPointer ());
@@ -1283,21 +1275,18 @@ bool AccessAnalysis::createCheckForAccess(
12831275
12841276 // If there's only one option for Ptr, look it up after bounds and wrap
12851277 // checking, because assumptions might have been added to PSE.
1286- if (TranslatedPtrs .size () == 1 ) {
1278+ if (RTCheckPtrs .size () == 1 ) {
12871279 AR =
12881280 cast<SCEVAddRecExpr>(replaceSymbolicStrideSCEV (PSE, StridesMap, Ptr));
12891281 P.setPointer (AR);
12901282 }
12911283
1292- // When we run after a failing dependency check we have to make sure
1293- // we don't have wrapping pointers.
1294- if (!isNoWrap (PSE, AR, TranslatedPtrs.size () == 1 ? Ptr : nullptr , AccessTy,
1295- TheLoop, Assume)) {
1284+ if (!isNoWrap (PSE, AR, RTCheckPtrs.size () == 1 ? Ptr : nullptr , AccessTy,
1285+ TheLoop, Assume))
12961286 return false ;
1297- }
12981287 }
12991288
1300- for (auto [PtrExpr, NeedsFreeze] : TranslatedPtrs ) {
1289+ for (const auto & [PtrExpr, NeedsFreeze] : RTCheckPtrs ) {
13011290 // The id of the dependence set.
13021291 unsigned DepId;
13031292
0 commit comments