Skip to content

Commit

Permalink
[LAA] We only need pointer checks if there are non-zero checks (NFC).
Browse files Browse the repository at this point in the history
If it turns out that we can do runtime checks, but there are no
runtime-checks to generate, set RtCheck.Need to false.

This can happen if we can prove statically that the pointers passed in
to canCheckPtrAtRT do not alias. This should not change any results, but
allows us to skip some work and assert that runtime checks are
generated, if LAA indicates that runtime checks are required.

Reviewers: anemet, Ayal

Reviewed By: Ayal

Differential Revision: https://reviews.llvm.org/D79969
  • Loading branch information
fhahn committed May 27, 2020
1 parent 706b22e commit 259abfc
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
26 changes: 16 additions & 10 deletions llvm/lib/Analysis/LoopAccessAnalysis.cpp
Expand Up @@ -701,12 +701,14 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
ScalarEvolution *SE, Loop *TheLoop,
const ValueToValueMap &StridesMap,
bool ShouldCheckWrap) {
if (!IsRTCheckAnalysisNeeded)
return true;

// Find pointers with computable bounds. We are going to use this information
// to place a runtime bound check.
bool CanDoRT = true;

bool NeedRTCheck = false;
if (!IsRTCheckAnalysisNeeded) return true;
RtCheck.Need = false;

bool IsDepCheckNeeded = isDependencyCheckNeeded();

Expand Down Expand Up @@ -747,10 +749,10 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
// check them. But there is no need to checks if there is only one
// dependence set for this alias set.
//
// Note that this function computes CanDoRT and NeedRTCheck independently.
// For example CanDoRT=false, NeedRTCheck=false means that we have a pointer
// for which we couldn't find the bounds but we don't actually need to emit
// any checks so it does not matter.
// Note that this function computes CanDoRT and RtCheck.Need independently.
// For example CanDoRT=false, RtCheck.Need=false means that we have a
// pointer for which we couldn't find the bounds but we don't actually need
// to emit any checks so it does not matter.
bool NeedsAliasSetRTCheck = false;
if (!(IsDepCheckNeeded && CanDoAliasSetRT && RunningDepId == 2))
NeedsAliasSetRTCheck = (NumWritePtrChecks >= 2 ||
Expand All @@ -773,7 +775,7 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
}

CanDoRT &= CanDoAliasSetRT;
NeedRTCheck |= NeedsAliasSetRTCheck;
RtCheck.Need |= NeedsAliasSetRTCheck;
++ASId;
}

Expand Down Expand Up @@ -807,15 +809,19 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
}
}

if (NeedRTCheck && CanDoRT)
if (RtCheck.Need && CanDoRT)
RtCheck.generateChecks(DepCands, IsDepCheckNeeded);

LLVM_DEBUG(dbgs() << "LAA: We need to do " << RtCheck.getNumberOfChecks()
<< " pointer comparisons.\n");

RtCheck.Need = NeedRTCheck;
// If we can do run-time checks, but there are no checks, no runtime checks
// are needed. This can happen when all pointers point to the same underlying
// object for example.
if (CanDoRT)
RtCheck.Need = RtCheck.getNumberOfChecks() != 0;

bool CanDoRTIfNeeded = !NeedRTCheck || CanDoRT;
bool CanDoRTIfNeeded = !RtCheck.Need || CanDoRT;
if (!CanDoRTIfNeeded)
RtCheck.reset();
return CanDoRTIfNeeded;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
Expand Up @@ -2795,8 +2795,8 @@ void InnerLoopVectorizer::emitMemRuntimeChecks(Loop *L, BasicBlock *Bypass) {
std::tie(FirstCheckInst, MemRuntimeCheck) =
addRuntimeChecks(MemCheckBlock->getTerminator(), OrigLoop,
RtPtrChecking.getChecks(), RtPtrChecking.getSE());
if (!MemRuntimeCheck)
return;
assert(MemRuntimeCheck && "no RT checks generated although RtPtrChecking "
"claimed checks are required");

if (MemCheckBlock->getParent()->hasOptSize()) {
assert(Cost->Hints->getForce() == LoopVectorizeHints::FK_Enabled &&
Expand Down

0 comments on commit 259abfc

Please sign in to comment.