mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-12 16:25:18 +00:00
Fix SCEV cache invalidation in LCSSA and LoopSimplify.
The LoopSimplify bug is pretty harmless because the loop goes from unanalyzable to analyzable but the LCSSA bug is very nasty. It only comes into play with a specific order of the LoopPassManager worklist and can cause actual miscompilations, when a SCEV refers to a value that has been replaced with PHI node. SCEVExpander may then insert code into the wrong place, either violating domination or randomly miscompiling stuff. Comes with an extensive test case reduced from the test-suite with bugpoint+SCEVValidator. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166787 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -53,6 +53,8 @@ namespace {
|
||||
|
||||
// Cached analysis information for the current function.
|
||||
DominatorTree *DT;
|
||||
LoopInfo *LI;
|
||||
ScalarEvolution *SE;
|
||||
std::vector<BasicBlock*> LoopBlocks;
|
||||
PredIteratorCache PredCache;
|
||||
Loop *L;
|
||||
@@ -117,6 +119,8 @@ bool LCSSA::runOnLoop(Loop *TheLoop, LPPassManager &LPM) {
|
||||
L = TheLoop;
|
||||
|
||||
DT = &getAnalysis<DominatorTree>();
|
||||
LI = &getAnalysis<LoopInfo>();
|
||||
SE = getAnalysisIfAvailable<ScalarEvolution>();
|
||||
|
||||
// Get the set of exiting blocks.
|
||||
SmallVector<BasicBlock*, 8> ExitBlocks;
|
||||
@@ -244,6 +248,12 @@ bool LCSSA::ProcessInstruction(Instruction *Inst,
|
||||
|
||||
// Remember that this phi makes the value alive in this block.
|
||||
SSAUpdate.AddAvailableValue(ExitBB, PN);
|
||||
|
||||
// If the exiting block is part of a loop inserting a PHI may change its
|
||||
// SCEV analysis. Conservatively drop any caches from it.
|
||||
if (SE)
|
||||
if (Loop *L = LI->getLoopFor(ExitBB))
|
||||
SE->forgetLoop(L);
|
||||
}
|
||||
|
||||
// Rewrite all uses outside the loop in terms of the new PHIs we just
|
||||
@@ -258,6 +268,10 @@ bool LCSSA::ProcessInstruction(Instruction *Inst,
|
||||
if (PHINode *PN = dyn_cast<PHINode>(User))
|
||||
UserBB = PN->getIncomingBlock(*UsesToRewrite[i]);
|
||||
|
||||
// Tell SCEV to reanalyze the value that's about to change.
|
||||
if (SE)
|
||||
SE->forgetValue(*UsesToRewrite[i]);
|
||||
|
||||
if (isa<PHINode>(UserBB->begin()) &&
|
||||
isExitBlock(UserBB, ExitBlocks)) {
|
||||
UsesToRewrite[i]->set(UserBB->begin());
|
||||
|
Reference in New Issue
Block a user