aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/LoopAccessAnalysis.cpp
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2025-02-16 19:56:12 +0100
committerFlorian Hahn <flo@fhahn.com>2025-02-16 19:56:13 +0100
commite080366a76b78a746c53caccf84661b109ccbc20 (patch)
treefcc06b06af243c500b98a65c0d7777f1dce7d07f /llvm/lib/Analysis/LoopAccessAnalysis.cpp
parent6e94007623ca9d98d090fe04491f21ec72a5d0d4 (diff)
downloadllvm-e080366a76b78a746c53caccf84661b109ccbc20.zip
llvm-e080366a76b78a746c53caccf84661b109ccbc20.tar.gz
llvm-e080366a76b78a746c53caccf84661b109ccbc20.tar.bz2
[LAA] Inline hasComputableBounds in only caller, simplify isNoWrap.
Inline hasComputableBounds into createCheckForAccess. This removes a level of indirection and allows for passing the AddRec directly to isNoWrap, removing the need to retrieve the AddRec for the pointer again. The early continue for invariant SCEVs now also applies to forked pointers (i.e. when there's more than one entry in TranslatedPtrs) when ShouldCheckWrap is true, as those trivially won't wrap. The change is NFC otherwise. replaceSymbolicStrideSCEV is now called earlier.
Diffstat (limited to 'llvm/lib/Analysis/LoopAccessAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/LoopAccessAnalysis.cpp59
1 files changed, 20 insertions, 39 deletions
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 43380b5..7d6dbd5 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -793,26 +793,6 @@ private:
} // end anonymous namespace
-/// Check whether a pointer can participate in a runtime bounds check.
-/// If \p Assume, try harder to prove that we can compute the bounds of \p Ptr
-/// by adding run-time checks (overflow checks) if necessary.
-static bool hasComputableBounds(PredicatedScalarEvolution &PSE, Value *Ptr,
- const SCEV *PtrScev, Loop *L, bool Assume) {
- // The bounds for loop-invariant pointer is trivial.
- if (PSE.getSE()->isLoopInvariant(PtrScev, L))
- return true;
-
- const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PtrScev);
-
- if (!AR && Assume)
- AR = PSE.getAsAddRec(Ptr);
-
- if (!AR)
- return false;
-
- return AR->isAffine();
-}
-
/// Try to compute the stride for \p AR. Used by getPtrStride.
static std::optional<int64_t>
getStrideFromAddRec(const SCEVAddRecExpr *AR, const Loop *Lp, Type *AccessTy,
@@ -859,21 +839,9 @@ static bool isNoWrapAddRec(Value *Ptr, const SCEVAddRecExpr *AR,
PredicatedScalarEvolution &PSE, const Loop *L);
/// Check whether a pointer address cannot wrap.
-static bool isNoWrap(PredicatedScalarEvolution &PSE,
- const DenseMap<Value *, const SCEV *> &Strides, Value *Ptr,
- Type *AccessTy, const Loop *L, bool Assume,
+static bool isNoWrap(PredicatedScalarEvolution &PSE, const SCEVAddRecExpr *AR,
+ Value *Ptr, Type *AccessTy, const Loop *L, bool Assume,
std::optional<int64_t> Stride = std::nullopt) {
- const SCEV *PtrScev = replaceSymbolicStrideSCEV(PSE, Strides, Ptr);
- if (PSE.getSE()->isLoopInvariant(PtrScev, L))
- return true;
-
- const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PtrScev);
- if (!AR) {
- if (!Assume)
- return false;
- AR = PSE.getAsAddRec(Ptr);
- }
-
// The address calculation must not wrap. Otherwise, a dependence could be
// inverted.
if (isNoWrapAddRec(Ptr, AR, PSE, L))
@@ -1143,14 +1111,27 @@ bool AccessAnalysis::createCheckForAccess(RuntimePointerChecking &RtCheck,
SmallVector<PointerIntPair<const SCEV *, 1, bool>> TranslatedPtrs =
findForkedPointer(PSE, StridesMap, Ptr, TheLoop);
+ /// Check whether all pointers can participate in a runtime bounds check. They
+ /// must either be invariant or AddRecs. If ShouldCheckWrap is true, they also
+ /// must not wrap.
for (auto &P : TranslatedPtrs) {
- if (!hasComputableBounds(PSE, Ptr, P.getPointer(), TheLoop, Assume))
+ // The bounds for loop-invariant pointer is trivial.
+ if (PSE.getSE()->isLoopInvariant(P.getPointer(), TheLoop))
+ continue;
+
+ const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(P.getPointer());
+ if (!AR && Assume)
+ AR = PSE.getAsAddRec(Ptr);
+ if (!AR || !AR->isAffine())
return false;
// If there's only one option for Ptr, look it up after bounds and wrap
// checking, because assumptions might have been added to PSE.
- if (TranslatedPtrs.size() == 1)
- P.setPointer(replaceSymbolicStrideSCEV(PSE, StridesMap, Ptr));
+ if (TranslatedPtrs.size() == 1) {
+ AR =
+ cast<SCEVAddRecExpr>(replaceSymbolicStrideSCEV(PSE, StridesMap, Ptr));
+ P.setPointer(AR);
+ }
// When we run after a failing dependency check we have to make sure
// we don't have wrapping pointers.
@@ -1159,7 +1140,7 @@ bool AccessAnalysis::createCheckForAccess(RuntimePointerChecking &RtCheck,
if (TranslatedPtrs.size() > 1)
return false;
- if (!isNoWrap(PSE, StridesMap, Ptr, AccessTy, TheLoop, Assume))
+ if (!isNoWrap(PSE, AR, Ptr, AccessTy, TheLoop, Assume))
return false;
}
}
@@ -1548,7 +1529,7 @@ llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr,
if (!ShouldCheckWrap || !Stride)
return Stride;
- if (isNoWrap(PSE, StridesMap, Ptr, AccessTy, Lp, Assume, Stride))
+ if (isNoWrap(PSE, AR, Ptr, AccessTy, Lp, Assume, Stride))
return Stride;
LLVM_DEBUG(