aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
diff options
context:
space:
mode:
authorMax Kazantsev <mkazantsev@azul.com>2020-09-10 13:29:45 +0700
committerMax Kazantsev <mkazantsev@azul.com>2020-09-10 13:30:31 +0700
commitc413a8a8ecd3c0ef7bcb08525fd73eb1392a738c (patch)
tree9d269ff01983e1caf1c81b5bd86703e7d403bbbf /llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
parent060c8e083dd637866854acb6a0823c45b2ef68ef (diff)
downloadllvm-c413a8a8ecd3c0ef7bcb08525fd73eb1392a738c.zip
llvm-c413a8a8ecd3c0ef7bcb08525fd73eb1392a738c.tar.gz
llvm-c413a8a8ecd3c0ef7bcb08525fd73eb1392a738c.tar.bz2
[LoopLoadElim] Filter away candidates that stop being AddRecs after loop versioning. PR47457
The test in PR47457 demonstrates a situation when candidate load's pointer's SCEV is no loger a SCEVAddRec after loop versioning. The code there assumes that it is always a SCEVAddRec and crashes otherwise. This patch makes sure that we do not consider candidates for which this requirement is broken after the versioning. Differential Revision: https://reviews.llvm.org/D87355 Reviewed By: asbirlea
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp25
1 files changed, 20 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp b/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
index 3b706956..e8473d6 100644
--- a/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp
@@ -486,7 +486,6 @@ public:
// Filter the candidates further.
SmallVector<StoreToLoadForwardingCandidate, 4> Candidates;
- unsigned NumForwarding = 0;
for (const StoreToLoadForwardingCandidate &Cand : StoreToLoadDependences) {
LLVM_DEBUG(dbgs() << "Candidate " << Cand);
@@ -506,12 +505,17 @@ public:
if (!Cand.isDependenceDistanceOfOne(PSE, L))
continue;
- ++NumForwarding;
+ assert(isa<SCEVAddRecExpr>(PSE.getSCEV(Cand.Load->getPointerOperand())) &&
+ "Loading from something other than indvar?");
+ assert(
+ isa<SCEVAddRecExpr>(PSE.getSCEV(Cand.Store->getPointerOperand())) &&
+ "Storing to something other than indvar?");
+
+ Candidates.push_back(Cand);
LLVM_DEBUG(
dbgs()
- << NumForwarding
+ << Candidates.size()
<< ". Valid store-to-load forwarding across the loop backedge\n");
- Candidates.push_back(Cand);
}
if (Candidates.empty())
return false;
@@ -563,6 +567,17 @@ public:
LV.setAliasChecks(std::move(Checks));
LV.setSCEVChecks(LAI.getPSE().getUnionPredicate());
LV.versionLoop();
+
+ // After versioning, some of the candidates' pointers could stop being
+ // SCEVAddRecs. We need to filter them out.
+ auto NoLongerGoodCandidate = [this](
+ const StoreToLoadForwardingCandidate &Cand) {
+ return !isa<SCEVAddRecExpr>(
+ PSE.getSCEV(Cand.Load->getPointerOperand())) ||
+ !isa<SCEVAddRecExpr>(
+ PSE.getSCEV(Cand.Store->getPointerOperand()));
+ };
+ llvm::erase_if(Candidates, NoLongerGoodCandidate);
}
// Next, propagate the value stored by the store to the users of the load.
@@ -571,7 +586,7 @@ public:
"storeforward");
for (const auto &Cand : Candidates)
propagateStoredValueToLoadUsers(Cand, SEE);
- NumLoopLoadEliminted += NumForwarding;
+ NumLoopLoadEliminted += Candidates.size();
return true;
}