summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-10-30 22:39:36 +0000
committerChris Lattner <sabre@nondot.org>2009-10-30 22:39:36 +0000
commitdd5d035302a1e80a2ed6cf51912598cc9e2f6ece (patch)
tree7321b35d602d254163ac39ba53c1a6509b5be514
parent1a9510660231c8bb379486af32d6a3722f4e025f (diff)
downloadbcm5719-llvm-dd5d035302a1e80a2ed6cf51912598cc9e2f6ece.tar.gz
bcm5719-llvm-dd5d035302a1e80a2ed6cf51912598cc9e2f6ece.zip
if basic blocks are destroyed while there are *just* BlockAddress' hanging
around, then zap them. This is analogous to dangling constantexprs hanging off functions. llvm-svn: 85627
-rw-r--r--llvm/lib/VMCore/BasicBlock.cpp18
-rw-r--r--llvm/test/Transforms/SimplifyCFG/basictest.ll9
2 files changed, 25 insertions, 2 deletions
diff --git a/llvm/lib/VMCore/BasicBlock.cpp b/llvm/lib/VMCore/BasicBlock.cpp
index e8069c0f053..23d0557dc74 100644
--- a/llvm/lib/VMCore/BasicBlock.cpp
+++ b/llvm/lib/VMCore/BasicBlock.cpp
@@ -58,6 +58,24 @@ BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
BasicBlock::~BasicBlock() {
+ // If the address of the block is taken and it is being deleted (e.g. because
+ // it is dead), this means that there is either a dangling constant expr
+ // hanging off the block, or an undefined use of the block (source code
+ // expecting the address of a label to keep the block alive even though there
+ // is no indirect branch). Handle these cases by zapping the BlockAddress
+ // nodes. There are no other possible uses at this point.
+ if (hasAddressTaken()) {
+ assert(!use_empty() && "There should be at least one blockaddress!");
+ Constant *Replacement =
+ ConstantInt::get(llvm::Type::getInt32Ty(getContext()), 1);
+ while (!use_empty()) {
+ BlockAddress *BA = cast<BlockAddress>(use_back());
+ BA->replaceAllUsesWith(ConstantExpr::getIntToPtr(Replacement,
+ BA->getType()));
+ BA->destroyConstant();
+ }
+ }
+
assert(getParent() == 0 && "BasicBlock still linked into the program!");
dropAllReferences();
InstList.clear();
diff --git a/llvm/test/Transforms/SimplifyCFG/basictest.ll b/llvm/test/Transforms/SimplifyCFG/basictest.ll
index 468b6ed11bc..a829e030e21 100644
--- a/llvm/test/Transforms/SimplifyCFG/basictest.ll
+++ b/llvm/test/Transforms/SimplifyCFG/basictest.ll
@@ -21,5 +21,10 @@ BB1: ; preds = %0, %0
}
-
-
+define void @test4() {
+entry:
+ br label %return
+return:
+ ret void
+}
+@test4g = global i8* blockaddress(@test4, %return)
OpenPOWER on IntegriCloud