@@ -530,8 +530,10 @@ void RuntimePointerChecking::groupChecks(
530
530
// equivalence class, the iteration order is deterministic.
531
531
for (auto M : DepCands.members (Access)) {
532
532
auto PointerI = PositionMap.find (M.getPointer ());
533
- assert (PointerI != PositionMap.end () &&
534
- " pointer in equivalence class not found in PositionMap" );
533
+ // If we can't find the pointer in PositionMap that means we can't
534
+ // generate a memcheck for it.
535
+ if (PointerI == PositionMap.end ())
536
+ continue ;
535
537
for (unsigned Pointer : PointerI->second ) {
536
538
bool Merged = false ;
537
539
// Mark this pointer as seen.
@@ -693,10 +695,13 @@ class AccessAnalysis {
693
695
// / non-intersection.
694
696
// /
695
697
// / Returns true if we need no check or if we do and we can generate them
696
- // / (i.e. the pointers have computable bounds).
698
+ // / (i.e. the pointers have computable bounds). A return value of false means
699
+ // / we couldn't analyze and generate runtime checks for all pointers in the
700
+ // / loop, but if \p AllowPartial is set then we will have checks for those
701
+ // / pointers we could analyze.
697
702
bool canCheckPtrAtRT (RuntimePointerChecking &RtCheck, Loop *TheLoop,
698
703
const DenseMap<Value *, const SCEV *> &Strides,
699
- Value *&UncomputablePtr);
704
+ Value *&UncomputablePtr, bool AllowPartial );
700
705
701
706
// / Goes over all memory accesses, checks whether a RT check is needed
702
707
// / and builds sets of dependent accesses.
@@ -1174,8 +1179,8 @@ bool AccessAnalysis::createCheckForAccess(
1174
1179
1175
1180
bool AccessAnalysis::canCheckPtrAtRT (
1176
1181
RuntimePointerChecking &RtCheck, Loop *TheLoop,
1177
- const DenseMap<Value *, const SCEV *> &StridesMap,
1178
- Value *&UncomputablePtr ) {
1182
+ const DenseMap<Value *, const SCEV *> &StridesMap, Value *&UncomputablePtr,
1183
+ bool AllowPartial ) {
1179
1184
// Find pointers with computable bounds. We are going to use this information
1180
1185
// to place a runtime bound check.
1181
1186
bool CanDoRT = true ;
@@ -1268,7 +1273,8 @@ bool AccessAnalysis::canCheckPtrAtRT(
1268
1273
/* Assume=*/ true )) {
1269
1274
CanDoAliasSetRT = false ;
1270
1275
UncomputablePtr = Access.getPointer ();
1271
- break ;
1276
+ if (!AllowPartial)
1277
+ break ;
1272
1278
}
1273
1279
}
1274
1280
}
@@ -1308,7 +1314,7 @@ bool AccessAnalysis::canCheckPtrAtRT(
1308
1314
}
1309
1315
}
1310
1316
1311
- if (MayNeedRTCheck && CanDoRT)
1317
+ if (MayNeedRTCheck && ( CanDoRT || AllowPartial) )
1312
1318
RtCheck.generateChecks (DepCands, IsDepCheckNeeded);
1313
1319
1314
1320
LLVM_DEBUG (dbgs () << " LAA: We need to do " << RtCheck.getNumberOfChecks ()
@@ -1322,7 +1328,7 @@ bool AccessAnalysis::canCheckPtrAtRT(
1322
1328
bool CanDoRTIfNeeded = !RtCheck.Need || CanDoRT;
1323
1329
assert (CanDoRTIfNeeded == (CanDoRT || !MayNeedRTCheck) &&
1324
1330
" CanDoRTIfNeeded depends on RtCheck.Need" );
1325
- if (!CanDoRTIfNeeded)
1331
+ if (!CanDoRTIfNeeded && !AllowPartial )
1326
1332
RtCheck.reset ();
1327
1333
return CanDoRTIfNeeded;
1328
1334
}
@@ -2592,9 +2598,9 @@ bool LoopAccessInfo::analyzeLoop(AAResults *AA, const LoopInfo *LI,
2592
2598
// Find pointers with computable bounds. We are going to use this information
2593
2599
// to place a runtime bound check.
2594
2600
Value *UncomputablePtr = nullptr ;
2595
- bool CanDoRTIfNeeded = Accesses.canCheckPtrAtRT (
2596
- *PtrRtChecking, TheLoop, SymbolicStrides, UncomputablePtr);
2597
- if (!CanDoRTIfNeeded ) {
2601
+ HasCompletePtrRtChecking = Accesses.canCheckPtrAtRT (
2602
+ *PtrRtChecking, TheLoop, SymbolicStrides, UncomputablePtr, AllowPartial );
2603
+ if (!HasCompletePtrRtChecking ) {
2598
2604
const auto *I = dyn_cast_or_null<Instruction>(UncomputablePtr);
2599
2605
recordAnalysis (" CantIdentifyArrayBounds" , I)
2600
2606
<< " cannot identify array bounds" ;
@@ -2622,11 +2628,12 @@ bool LoopAccessInfo::analyzeLoop(AAResults *AA, const LoopInfo *LI,
2622
2628
PtrRtChecking->Need = true ;
2623
2629
2624
2630
UncomputablePtr = nullptr ;
2625
- CanDoRTIfNeeded = Accesses.canCheckPtrAtRT (
2626
- *PtrRtChecking, TheLoop, SymbolicStrides, UncomputablePtr);
2631
+ HasCompletePtrRtChecking =
2632
+ Accesses.canCheckPtrAtRT (*PtrRtChecking, TheLoop, SymbolicStrides,
2633
+ UncomputablePtr, AllowPartial);
2627
2634
2628
2635
// Check that we found the bounds for the pointer.
2629
- if (!CanDoRTIfNeeded ) {
2636
+ if (!HasCompletePtrRtChecking ) {
2630
2637
auto *I = dyn_cast_or_null<Instruction>(UncomputablePtr);
2631
2638
recordAnalysis (" CantCheckMemDepsAtRunTime" , I)
2632
2639
<< " cannot check memory dependencies at runtime" ;
@@ -2901,9 +2908,10 @@ void LoopAccessInfo::collectStridedAccess(Value *MemAccess) {
2901
2908
LoopAccessInfo::LoopAccessInfo (Loop *L, ScalarEvolution *SE,
2902
2909
const TargetTransformInfo *TTI,
2903
2910
const TargetLibraryInfo *TLI, AAResults *AA,
2904
- DominatorTree *DT, LoopInfo *LI)
2911
+ DominatorTree *DT, LoopInfo *LI,
2912
+ bool AllowPartial)
2905
2913
: PSE(std::make_unique<PredicatedScalarEvolution>(*SE, *L)),
2906
- PtrRtChecking (nullptr ), TheLoop(L) {
2914
+ PtrRtChecking (nullptr ), TheLoop(L), AllowPartial(AllowPartial) {
2907
2915
unsigned MaxTargetVectorWidthInBits = std::numeric_limits<unsigned >::max ();
2908
2916
if (TTI && !TTI->enableScalableVectorization ())
2909
2917
// Scale the vector width by 2 as rough estimate to also consider
@@ -2952,6 +2960,8 @@ void LoopAccessInfo::print(raw_ostream &OS, unsigned Depth) const {
2952
2960
2953
2961
// List the pair of accesses need run-time checks to prove independence.
2954
2962
PtrRtChecking->print (OS, Depth);
2963
+ if (PtrRtChecking->Need && !HasCompletePtrRtChecking)
2964
+ OS.indent (Depth) << " Generated run-time checks are incomplete\n " ;
2955
2965
OS << " \n " ;
2956
2966
2957
2967
OS.indent (Depth)
@@ -2971,12 +2981,15 @@ void LoopAccessInfo::print(raw_ostream &OS, unsigned Depth) const {
2971
2981
PSE->print (OS, Depth);
2972
2982
}
2973
2983
2974
- const LoopAccessInfo &LoopAccessInfoManager::getInfo (Loop &L) {
2984
+ const LoopAccessInfo &LoopAccessInfoManager::getInfo (Loop &L,
2985
+ bool AllowPartial) {
2975
2986
const auto &[It, Inserted] = LoopAccessInfoMap.try_emplace (&L);
2976
2987
2977
- if (Inserted)
2978
- It->second =
2979
- std::make_unique<LoopAccessInfo>(&L, &SE, TTI, TLI, &AA, &DT, &LI);
2988
+ // We need to create the LoopAccessInfo if either we don't already have one,
2989
+ // or if it was created with a different value of AllowPartial.
2990
+ if (Inserted || It->second ->hasAllowPartial () != AllowPartial)
2991
+ It->second = std::make_unique<LoopAccessInfo>(&L, &SE, TTI, TLI, &AA, &DT,
2992
+ &LI, AllowPartial);
2980
2993
2981
2994
return *It->second ;
2982
2995
}
0 commit comments