@@ -1231,48 +1231,40 @@ static void findForkedSCEVs(
1231
1231
}
1232
1232
}
1233
1233
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
-
1259
1234
bool AccessAnalysis::createCheckForAccess (
1260
1235
RuntimePointerChecking &RtCheck, MemAccessInfo Access, Type *AccessTy,
1261
1236
const DenseMap<Value *, const SCEV *> &StridesMap,
1262
1237
DenseMap<Value *, unsigned > &DepSetId, Loop *TheLoop,
1263
1238
unsigned &RunningDepId, unsigned ASId, bool Assume) {
1264
1239
Value *Ptr = Access.getPointer ();
1240
+ ScalarEvolution *SE = PSE.getSE ();
1241
+ assert (SE->isSCEVable (Ptr->getType ()) && " Value is not SCEVable!" );
1265
1242
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
+ }
1269
1262
1270
1263
// / 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) {
1274
1266
// The bounds for loop-invariant pointer is trivial.
1275
- if (PSE. getSE () ->isLoopInvariant (P.getPointer (), TheLoop))
1267
+ if (SE ->isLoopInvariant (P.getPointer (), TheLoop))
1276
1268
continue ;
1277
1269
1278
1270
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(P.getPointer ());
@@ -1283,21 +1275,18 @@ bool AccessAnalysis::createCheckForAccess(
1283
1275
1284
1276
// If there's only one option for Ptr, look it up after bounds and wrap
1285
1277
// checking, because assumptions might have been added to PSE.
1286
- if (TranslatedPtrs .size () == 1 ) {
1278
+ if (RTCheckPtrs .size () == 1 ) {
1287
1279
AR =
1288
1280
cast<SCEVAddRecExpr>(replaceSymbolicStrideSCEV (PSE, StridesMap, Ptr));
1289
1281
P.setPointer (AR);
1290
1282
}
1291
1283
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))
1296
1286
return false ;
1297
- }
1298
1287
}
1299
1288
1300
- for (auto [PtrExpr, NeedsFreeze] : TranslatedPtrs ) {
1289
+ for (const auto & [PtrExpr, NeedsFreeze] : RTCheckPtrs ) {
1301
1290
// The id of the dependence set.
1302
1291
unsigned DepId;
1303
1292
0 commit comments