llvm.org GIT mirror llvm / 78f7a25
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125829 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 8 years ago
2 changed file(s) with 45 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
605605 return MinSucc;
606606 }
607607
608 static bool hasAddressTakenAndUsed(BasicBlock *BB) {
609 if (!BB->hasAddressTaken()) return false;
610
611 // If the block has its address taken, it may be a tree of dead constants
612 // hanging off of it. These shouldn't keep the block alive.
613 BlockAddress *BA = BlockAddress::get(BB);
614 BA->removeDeadConstantUsers();
615 return !BA->use_empty();
616 }
617
608618 /// ProcessBlock - If there are any predecessors whose control can be threaded
609619 /// through to a successor, transform them now.
610620 bool JumpThreading::ProcessBlock(BasicBlock *BB) {
620630 // predecessors of our predecessor block.
621631 if (BasicBlock *SinglePred = BB->getSinglePredecessor()) {
622632 if (SinglePred->getTerminator()->getNumSuccessors() == 1 &&
623 SinglePred != BB) {
633 SinglePred != BB && !hasAddressTakenAndUsed(BB)) {
624634 // If SinglePred was a loop header, BB becomes one.
625635 if (LoopHeaders.erase(SinglePred))
626636 LoopHeaders.insert(BB);
4343 ; Check constant folding of indirectbr
4444
4545 ; CHECK: void @test2
46 ; CHECK-NEXT: :
46 ; CHECK: entry:
47 ; CHECK-NEXT: br label %L1
48 ; CHECK: L1:
4749 ; CHECK-NEXT: call void @bar
4850 ; CHECK-NEXT: ret void
4951 define void @test2() nounwind {
5860 call void @baz()
5961 ret void
6062 }
63
64
65 ; PR4151
66 ; Don't merge address-taken blocks.
67 @.str = private unnamed_addr constant [4 x i8] c"%p\0A\00"
68
69 ; CHECK: @test3
70 ; CHECK: __here:
71 ; CHECK: blockaddress(@test3, %__here)
72 ; CHECK: __here1:
73 ; CHECK: blockaddress(@test3, %__here1)
74 ; CHECK: __here3:
75 ; CHECK: blockaddress(@test3, %__here3)
76 define void @test3() nounwind ssp noredzone {
77 entry:
78 br label %__here
79
80 __here: ; preds = %entry
81 %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
82 br label %__here1
83
84 __here1: ; preds = %__here
85 %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
86 br label %__here3
87
88 __here3: ; preds = %__here1
89 %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
90 ret void
91 }
92
93 declare i32 @printf(...) noredzone