diff options
| author | Chris Lattner <sabre@nondot.org> | 2011-02-18 04:43:06 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2011-02-18 04:43:06 +0000 |
| commit | 1a924e770ad01b524d7477473a1ded63c90242aa (patch) | |
| tree | 90fa3eaa6a10abfc4c8b04086fb1f8a836b9040e /llvm | |
| parent | 8488640da7f65d06703b53eddf1f36ba8f216072 (diff) | |
| download | bcm5719-llvm-1a924e770ad01b524d7477473a1ded63c90242aa.tar.gz bcm5719-llvm-1a924e770ad01b524d7477473a1ded63c90242aa.zip | |
prevent jump threading from merging blocks when their address is
taken (and used!). This prevents merging the blocks (invalidating
the block addresses) in a case like this:
#define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; })
void foo() {
printf("%p\n", _THIS_IP_);
printf("%p\n", _THIS_IP_);
printf("%p\n", _THIS_IP_);
}
which fixes PR4151.
llvm-svn: 125829
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/JumpThreading.cpp | 12 | ||||
| -rw-r--r-- | llvm/test/Transforms/JumpThreading/indirectbr.ll | 35 |
2 files changed, 45 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index 3d218a6585a..90094a8da25 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -606,6 +606,16 @@ static unsigned GetBestDestForJumpOnUndef(BasicBlock *BB) { return MinSucc; } +static bool hasAddressTakenAndUsed(BasicBlock *BB) { + if (!BB->hasAddressTaken()) return false; + + // If the block has its address taken, it may be a tree of dead constants + // hanging off of it. These shouldn't keep the block alive. + BlockAddress *BA = BlockAddress::get(BB); + BA->removeDeadConstantUsers(); + return !BA->use_empty(); +} + /// ProcessBlock - If there are any predecessors whose control can be threaded /// through to a successor, transform them now. bool JumpThreading::ProcessBlock(BasicBlock *BB) { @@ -621,7 +631,7 @@ bool JumpThreading::ProcessBlock(BasicBlock *BB) { // predecessors of our predecessor block. if (BasicBlock *SinglePred = BB->getSinglePredecessor()) { if (SinglePred->getTerminator()->getNumSuccessors() == 1 && - SinglePred != BB) { + SinglePred != BB && !hasAddressTakenAndUsed(BB)) { // If SinglePred was a loop header, BB becomes one. if (LoopHeaders.erase(SinglePred)) LoopHeaders.insert(BB); diff --git a/llvm/test/Transforms/JumpThreading/indirectbr.ll b/llvm/test/Transforms/JumpThreading/indirectbr.ll index 6c5321d3194..141277fec62 100644 --- a/llvm/test/Transforms/JumpThreading/indirectbr.ll +++ b/llvm/test/Transforms/JumpThreading/indirectbr.ll @@ -44,7 +44,9 @@ indirectgoto: ; preds = %if.else, %entry ; Check constant folding of indirectbr ; CHECK: void @test2 -; CHECK-NEXT: : +; CHECK: entry: +; CHECK-NEXT: br label %L1 +; CHECK: L1: ; CHECK-NEXT: call void @bar ; CHECK-NEXT: ret void define void @test2() nounwind { @@ -59,3 +61,34 @@ L2: ; preds = %indirectgoto call void @baz() ret void } + + +; PR4151 +; Don't merge address-taken blocks. +@.str = private unnamed_addr constant [4 x i8] c"%p\0A\00" + +; CHECK: @test3 +; CHECK: __here: +; CHECK: blockaddress(@test3, %__here) +; CHECK: __here1: +; CHECK: blockaddress(@test3, %__here1) +; CHECK: __here3: +; CHECK: blockaddress(@test3, %__here3) +define void @test3() nounwind ssp noredzone { +entry: + br label %__here + +__here: ; preds = %entry + %call = call i32 (...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i64 ptrtoint (i8* blockaddress(@test3, %__here) to i64)) nounwind noredzone + br label %__here1 + +__here1: ; preds = %__here + %call2 = call i32 (...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i64 ptrtoint (i8* blockaddress(@test3, %__here1) to i64)) nounwind noredzone + br label %__here3 + +__here3: ; preds = %__here1 + %call4 = call i32 (...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i64 0, i64 0), i64 ptrtoint (i8* blockaddress(@test3, %__here3) to i64)) nounwind noredzone + ret void +} + +declare i32 @printf(...) noredzone |

