From 7f0566c1233ba4378c2c5531ddbc9eb8ad1868da Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 6 Jul 2004 06:36:11 +0000 Subject: [PATCH] Fix a bug in the unreachable block elim pass. Dropping all references on a basic block clear()'s all of the operands lists, including phis. This caused removePredecessor to get confused later. Because of this, we just nuke (without prejudice) PHI nodes in unreachable blocks. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14635 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/UnreachableBlockElim.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/CodeGen/UnreachableBlockElim.cpp b/lib/CodeGen/UnreachableBlockElim.cpp index bcc124538d3..1b59ac4a666 100644 --- a/lib/CodeGen/UnreachableBlockElim.cpp +++ b/lib/CodeGen/UnreachableBlockElim.cpp @@ -21,6 +21,8 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/Passes.h" +#include "llvm/iPHINode.h" +#include "llvm/Constant.h" #include "llvm/Function.h" #include "llvm/Pass.h" #include "llvm/Support/CFG.h" @@ -52,10 +54,15 @@ bool UnreachableBlockElim::runOnFunction(Function &F) { std::vector DeadBlocks; for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) if (!Reachable.count(I)) { - DeadBlocks.push_back(I); - for (succ_iterator SI = succ_begin(&*I), E = succ_end(&*I); SI != E; ++SI) - (*SI)->removePredecessor(I); - I->dropAllReferences(); + BasicBlock *BB = I; + DeadBlocks.push_back(BB); + while (PHINode *PN = dyn_cast(BB->begin())) { + PN->replaceAllUsesWith(Constant::getNullValue(PN->getType())); + BB->getInstList().pop_front(); + } + for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI) + (*SI)->removePredecessor(BB); + BB->dropAllReferences(); } if (DeadBlocks.empty()) return false;