diff options
author | Chris Lattner <sabre@nondot.org> | 2006-08-03 21:40:24 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-08-03 21:40:24 +0000 |
commit | 8cfe6335e40a1190e96e470b35a760a2bad7f650 (patch) | |
tree | 43fe6355e302186910851eb6fe9e4cbc9e31a333 /lib | |
parent | 006f2d0afde039220fc13f36ddc77e36d019226e (diff) |
Fix PR867 (and maybe 868) and testcsae:
Transforms/SimplifyCFG/2006-08-03-Crash.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29515 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/Utils/SimplifyCFG.cpp | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index 8f7a154cf4..7ac944446e 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -459,12 +459,31 @@ static bool GatherValueComparisons(Instruction *Cond, Value *&CompVal, /// has no side effects, nuke it. If it uses any instructions that become dead /// because the instruction is now gone, nuke them too. static void ErasePossiblyDeadInstructionTree(Instruction *I) { - if (isInstructionTriviallyDead(I)) { - std::vector<Value*> Operands(I->op_begin(), I->op_end()); - I->getParent()->getInstList().erase(I); - for (unsigned i = 0, e = Operands.size(); i != e; ++i) - if (Instruction *OpI = dyn_cast<Instruction>(Operands[i])) - ErasePossiblyDeadInstructionTree(OpI); + if (!isInstructionTriviallyDead(I)) return; + + std::vector<Instruction*> InstrsToInspect; + InstrsToInspect.push_back(I); + + while (!InstrsToInspect.empty()) { + I = InstrsToInspect.back(); + InstrsToInspect.pop_back(); + + if (!isInstructionTriviallyDead(I)) continue; + + // If I is in the work list multiple times, remove previous instances. + for (unsigned i = 0, e = InstrsToInspect.size(); i != e; ++i) + if (InstrsToInspect[i] == I) { + InstrsToInspect.erase(InstrsToInspect.begin()+i); + --i, --e; + } + + // Add operands of dead instruction to worklist. + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + if (Instruction *OpI = dyn_cast<Instruction>(I->getOperand(i))) + InstrsToInspect.push_back(OpI); + + // Remove dead instruction. + I->eraseFromParent(); } } |