diff options
author | Max Kazantsev <mkazantsev@azul.com> | 2020-09-10 13:29:45 +0700 |
---|---|---|
committer | Max Kazantsev <mkazantsev@azul.com> | 2020-09-10 13:30:31 +0700 |
commit | c413a8a8ecd3c0ef7bcb08525fd73eb1392a738c (patch) | |
tree | 9d269ff01983e1caf1c81b5bd86703e7d403bbbf /llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp | |
parent | 060c8e083dd637866854acb6a0823c45b2ef68ef (diff) | |
download | llvm-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.cpp | 25 |
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; } |