From 3f945c295e6add83a10058f9ec85d36bdf97cf96 Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Wed, 2 Sep 2015 22:25:07 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@246718 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/RewriteStatepointsForGC.cpp | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp index e4a05bbeadd..7563cea9a04 100644 --- a/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ b/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 ReverseMap; SmallPtrSet NewInsts; - SmallSetVector Worklist; + SmallSetVector, 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(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(def)->getModule()->getDataLayout(); while (!Worklist.empty()) { @@ -1055,22 +1065,12 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) { if (auto *BdvI = dyn_cast(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; } } -- 2.34.1