Index: lib/Transforms/Scalar/RewriteStatepointsForGC.cpp =================================================================== --- lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -1024,7 +1024,7 @@ // 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,19 @@ 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(); + states[BDV] = BDVState(BDVState::Conflict, Replacement); }; const DataLayout &DL = cast(def)->getModule()->getDataLayout(); while (!Worklist.empty()) { @@ -1055,22 +1063,12 @@ 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; } }