summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/LoopAccessAnalysis.cpp
diff options
context:
space:
mode:
authorAdam Nemet <anemet@apple.com>2016-03-24 04:28:47 +0000
committerAdam Nemet <anemet@apple.com>2016-03-24 04:28:47 +0000
commit279784ffc4e48fa7da8bd2c57ee0e31789a1bed1 (patch)
treeec20b6857461d3d4efec40c558d029cd481220a1 /llvm/lib/Analysis/LoopAccessAnalysis.cpp
parent972bea8a2e56cd3651e79a6080ad94cfeb8f887f (diff)
downloadbcm5719-llvm-279784ffc4e48fa7da8bd2c57ee0e31789a1bed1.tar.gz
bcm5719-llvm-279784ffc4e48fa7da8bd2c57ee0e31789a1bed1.zip
[LAA] Support memchecks involving loop-invariant addresses
We used to only allow SCEVAddRecExpr for pointer expressions in order to be able to compute the bounds. However this is also trivially possible for loop-invariant addresses (scUnknown) since then the bounds are the address itself. Interestingly, we used allow this for the special case when the loop-invariant address happens to also be an SCEVAddRecExpr (in an outer loop). There are a couple more loops that are vectorized in SPEC after this. My guess is that the main reason we don't see more because for example a loop-invariant load is vectorized into a splat vector with several vector-inserts. This is likely to make the vectorization unprofitable. I.e. we don't notice that a later LICM will move all of this out of the loop so the cost estimate should really be 0. llvm-svn: 264243
Diffstat (limited to 'llvm/lib/Analysis/LoopAccessAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/LoopAccessAnalysis.cpp48
1 files changed, 31 insertions, 17 deletions
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index 04a4b1fa5a3..e3d0d25411b 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -130,26 +130,35 @@ void RuntimePointerChecking::insert(Loop *Lp, Value *Ptr, bool WritePtr,
PredicatedScalarEvolution &PSE) {
// Get the stride replaced scev.
const SCEV *Sc = replaceSymbolicStrideSCEV(PSE, Strides, Ptr);
- const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Sc);
- assert(AR && "Invalid addrec expression");
ScalarEvolution *SE = PSE.getSE();
- const SCEV *Ex = SE->getBackedgeTakenCount(Lp);
- const SCEV *ScStart = AR->getStart();
- const SCEV *ScEnd = AR->evaluateAtIteration(Ex, *SE);
- const SCEV *Step = AR->getStepRecurrence(*SE);
+ const SCEV *ScStart;
+ const SCEV *ScEnd;
- // For expressions with negative step, the upper bound is ScStart and the
- // lower bound is ScEnd.
- if (const SCEVConstant *CStep = dyn_cast<const SCEVConstant>(Step)) {
- if (CStep->getValue()->isNegative())
- std::swap(ScStart, ScEnd);
- } else {
- // Fallback case: the step is not constant, but the we can still
- // get the upper and lower bounds of the interval by using min/max
- // expressions.
- ScStart = SE->getUMinExpr(ScStart, ScEnd);
- ScEnd = SE->getUMaxExpr(AR->getStart(), ScEnd);
+ if (SE->isLoopInvariant(Sc, Lp)) {
+ ScStart = ScEnd = Sc;
+ }
+ else {
+ const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Sc);
+ assert(AR && "Invalid addrec expression");
+ const SCEV *Ex = SE->getBackedgeTakenCount(Lp);
+
+ ScStart = AR->getStart();
+ ScEnd = AR->evaluateAtIteration(Ex, *SE);
+ const SCEV *Step = AR->getStepRecurrence(*SE);
+
+ // For expressions with negative step, the upper bound is ScStart and the
+ // lower bound is ScEnd.
+ if (const SCEVConstant *CStep = dyn_cast<const SCEVConstant>(Step)) {
+ if (CStep->getValue()->isNegative())
+ std::swap(ScStart, ScEnd);
+ } else {
+ // Fallback case: the step is not constant, but the we can still
+ // get the upper and lower bounds of the interval by using min/max
+ // expressions.
+ ScStart = SE->getUMinExpr(ScStart, ScEnd);
+ ScEnd = SE->getUMaxExpr(AR->getStart(), ScEnd);
+ }
}
Pointers.emplace_back(Ptr, ScStart, ScEnd, WritePtr, DepSetId, ASId, Sc);
@@ -524,6 +533,11 @@ static bool hasComputableBounds(PredicatedScalarEvolution &PSE,
const ValueToValueMap &Strides, Value *Ptr,
Loop *L) {
const SCEV *PtrScev = replaceSymbolicStrideSCEV(PSE, Strides, Ptr);
+
+ // 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)
return false;
OpenPOWER on IntegriCloud