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