diff options
| author | Philip Reames <listmail@philipreames.com> | 2015-09-02 22:25:07 +0000 |
|---|---|---|
| committer | Philip Reames <listmail@philipreames.com> | 2015-09-02 22:25:07 +0000 |
| commit | 9546f367f7110b17169d628a9fa66310b2c27256 (patch) | |
| tree | c0a960aeba2bdfe5a67732387fb9bcd20720f6a1 /llvm/lib | |
| parent | 6906e928122e79a0d024d655b54d84b1d591d2ba (diff) | |
| download | bcm5719-llvm-9546f367f7110b17169d628a9fa66310b2c27256.tar.gz bcm5719-llvm-9546f367f7110b17169d628a9fa66310b2c27256.zip | |
[RewriteStatepointsForGC] Bugfix for change 246133
Fix a bug in change 246133. I didn't handle the case where we had a cycle in the use graph and could add an instruction we were about to erase back on to the worklist. Oddly, I have not been able to write a small test case for this, even with the AssertingVH added. I have confirmed the basic theory for the fix on a large failing example, but all attempts to reduce that to something appropriate for a test case have failed.
Differential Revision: http://reviews.llvm.org/D12575
llvm-svn: 246718
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp | 32 |
1 files changed, 16 insertions, 16 deletions
diff --git a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp index e4a05bbeadd..7563cea9a04 100644 --- a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -1024,7 +1024,7 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) { // doing as a post process step is easier to reason about for the moment. DenseMap<Value *, Value *> ReverseMap; SmallPtrSet<Instruction *, 16> NewInsts; - SmallSetVector<Instruction *, 16> Worklist; + SmallSetVector<AssertingVH<Instruction>, 16> Worklist; for (auto Item : states) { Value *V = Item.first; Value *Base = Item.second.getBase(); @@ -1041,11 +1041,21 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) { Worklist.insert(BaseI); } } - auto PushNewUsers = [&](Instruction *I) { - for (User *U : I->users()) + auto ReplaceBaseInstWith = [&](Value *BDV, Instruction *BaseI, + Value *Replacement) { + // Add users which are new instructions (excluding self references) + for (User *U : BaseI->users()) if (auto *UI = dyn_cast<Instruction>(U)) - if (NewInsts.count(UI)) + if (NewInsts.count(UI) && UI != BaseI) Worklist.insert(UI); + // Then do the actual replacement + NewInsts.erase(BaseI); + ReverseMap.erase(BaseI); + BaseI->replaceAllUsesWith(Replacement); + BaseI->eraseFromParent(); + assert(states.count(BDV)); + assert(states[BDV].isConflict() && states[BDV].getBase() == BaseI); + states[BDV] = BDVState(BDVState::Conflict, Replacement); }; const DataLayout &DL = cast<Instruction>(def)->getModule()->getDataLayout(); while (!Worklist.empty()) { @@ -1055,22 +1065,12 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) { if (auto *BdvI = dyn_cast<Instruction>(Bdv)) if (BaseI->isIdenticalTo(BdvI)) { DEBUG(dbgs() << "Identical Base: " << *BaseI << "\n"); - PushNewUsers(BaseI); - BaseI->replaceAllUsesWith(Bdv); - BaseI->eraseFromParent(); - states[Bdv] = BDVState(BDVState::Conflict, Bdv); - NewInsts.erase(BaseI); - ReverseMap.erase(BaseI); + ReplaceBaseInstWith(Bdv, BaseI, Bdv); continue; } if (Value *V = SimplifyInstruction(BaseI, DL)) { DEBUG(dbgs() << "Base " << *BaseI << " simplified to " << *V << "\n"); - PushNewUsers(BaseI); - BaseI->replaceAllUsesWith(V); - BaseI->eraseFromParent(); - states[Bdv] = BDVState(BDVState::Conflict, V); - NewInsts.erase(BaseI); - ReverseMap.erase(BaseI); + ReplaceBaseInstWith(Bdv, BaseI, V); continue; } } |

