Index: llvm/lib/Transforms/Scalar/SROA.cpp =================================================================== --- llvm/lib/Transforms/Scalar/SROA.cpp +++ llvm/lib/Transforms/Scalar/SROA.cpp @@ -1263,7 +1263,9 @@ return true; } -static void speculatePHINodeLoads(PHINode &PN) { +typedef SetVector> DeadInstsTy; + +static void speculatePHINodeLoads(PHINode &PN, DeadInstsTy &DeadInsts) { LLVM_DEBUG(dbgs() << " original: " << PN << "\n"); LoadInst *SomeLoad = cast(PN.user_back()); @@ -1282,6 +1284,9 @@ while (!PN.use_empty()) { LoadInst *LI = cast(PN.user_back()); LI->replaceAllUsesWith(NewPN); + // Remove from DeadInsts to avoid dangling pointers + if (DeadInsts.count(LI) > 0) + DeadInsts.remove(LI); LI->eraseFromParent(); } @@ -1354,7 +1359,7 @@ return true; } -static void speculateSelectInstLoads(SelectInst &SI) { +static void speculateSelectInstLoads(SelectInst &SI, DeadInstsTy &DeadInsts) { LLVM_DEBUG(dbgs() << " original: " << SI << "\n"); IRBuilderTy IRB(&SI); @@ -1365,6 +1370,13 @@ LoadInst *LI = cast(SI.user_back()); assert(LI->isSimple() && "We only speculate simple loads"); + // Do not have to process DEAD Loads + if (DeadInsts.count(LI) > 0) { + DeadInsts.remove(LI); + LI->eraseFromParent(); + continue; + } + IRB.SetInsertPoint(LI); LoadInst *TL = IRB.CreateLoad(LI->getType(), TV, LI->getName() + ".sroa.speculate.load.true"); @@ -4664,11 +4676,11 @@ LLVM_DEBUG(dbgs() << " Speculating PHIs\n"); while (!SpeculatablePHIs.empty()) - speculatePHINodeLoads(*SpeculatablePHIs.pop_back_val()); + speculatePHINodeLoads(*SpeculatablePHIs.pop_back_val(), DeadInsts); LLVM_DEBUG(dbgs() << " Speculating Selects\n"); while (!SpeculatableSelects.empty()) - speculateSelectInstLoads(*SpeculatableSelects.pop_back_val()); + speculateSelectInstLoads(*SpeculatableSelects.pop_back_val(), DeadInsts); return Changed; }