1; RUN: opt -S -ipsccp < %s | FileCheck %s 2 3declare void @BB0_f() 4declare void @BB1_f() 5 6; Make sure we can eliminate what is in BB0 as we know that the indirectbr is going to BB1. 7; 8; CHECK-LABEL: define void @indbrtest1( 9; CHECK-NOT: call void @BB0_f() 10; CHECK: ret void 11define void @indbrtest1() { 12entry: 13 indirectbr i8* blockaddress(@indbrtest1, %BB1), [label %BB0, label %BB1] 14BB0: 15 call void @BB0_f() 16 br label %BB1 17BB1: 18 call void @BB1_f() 19 ret void 20} 21 22; Make sure we can eliminate what is in BB0 as we know that the indirectbr is going to BB1 23; by looking through the casts. The casts should be folded away when they are visited 24; before the indirectbr instruction. 25; 26; CHECK-LABEL: define void @indbrtest2( 27; CHECK-NOT: call void @BB0_f() 28; CHECK: ret void 29define void @indbrtest2() { 30entry: 31 %a = ptrtoint i8* blockaddress(@indbrtest2, %BB1) to i64 32 %b = inttoptr i64 %a to i8* 33 %c = bitcast i8* %b to i8* 34 indirectbr i8* %b, [label %BB0, label %BB1] 35BB0: 36 call void @BB0_f() 37 br label %BB1 38BB1: 39 call void @BB1_f() 40 ret void 41} 42 43; Make sure we can not eliminate BB0 as we do not know the target of the indirectbr. 44; 45; CHECK-LABEL: define void @indbrtest3( 46; CHECK: call void @BB0_f() 47; CHECK: ret void 48define void @indbrtest3(i8** %Q) { 49entry: 50 %t = load i8*, i8** %Q 51 indirectbr i8* %t, [label %BB0, label %BB1] 52BB0: 53 call void @BB0_f() 54 br label %BB1 55BB1: 56 call void @BB1_f() 57 ret void 58} 59 60; Make sure we eliminate BB1 as we pick the first successor on undef. 61; 62; CHECK-LABEL: define void @indbrtest4( 63; CHECK: call void @BB0_f() 64; CHECK: ret void 65define void @indbrtest4(i8** %Q) { 66entry: 67 indirectbr i8* undef, [label %BB0, label %BB1] 68BB0: 69 call void @BB0_f() 70 br label %BB1 71BB1: 72 call void @BB1_f() 73 ret void 74} 75 76 77; CHECK-LABEL: define internal i32 @indbrtest5( 78; CHECK: ret i32 undef 79define internal i32 @indbrtest5(i1 %c) { 80entry: 81 br i1 %c, label %bb1, label %bb2 82 83bb1: 84 br label %branch.block 85 86 87bb2: 88 br label %branch.block 89 90branch.block: 91 %addr = phi i8* [blockaddress(@indbrtest5, %target1), %bb1], [blockaddress(@indbrtest5, %target2), %bb2] 92 indirectbr i8* %addr, [label %target1, label %target2] 93 94target1: 95 br label %target2 96 97target2: 98 ret i32 10 99} 100 101 102define i32 @indbrtest5_callee(i1 %c) { 103; CHECK-LABEL: define i32 @indbrtest5_callee( 104; CHECK-NEXT: %r = call i32 @indbrtest5(i1 %c) 105; CHECK-NEXT: ret i32 10 106 %r = call i32 @indbrtest5(i1 %c) 107 ret i32 %r 108} 109