Skip to content

Commit

Permalink
prevent jump threading from merging blocks when their address is
Browse files Browse the repository at this point in the history
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.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125829 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
lattner committed Feb 18, 2011
1 parent 13fb0db commit 78f7a25
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
12 changes: 11 additions & 1 deletion lib/Transforms/Scalar/JumpThreading.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand Down
35 changes: 34 additions & 1 deletion test/Transforms/JumpThreading/indirectbr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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

0 comments on commit 78f7a25

Please sign in to comment.