Update Transforms tests to use CHECK-LABEL for easier debugging. No functionality...
[oota-llvm.git] / test / Transforms / SimplifyCFG / indirectbr.ll
1 ; RUN: opt -S -simplifycfg < %s | FileCheck %s
2
3 ; SimplifyCFG should eliminate redundant indirectbr edges.
4
5 ; CHECK: indbrtest0
6 ; CHECK: indirectbr i8* %t, [label %BB0, label %BB1, label %BB2]
7 ; CHECK: %x = phi i32 [ 0, %BB0 ], [ 1, %entry ]
8
9 declare void @foo()
10 declare void @A()
11 declare void @B(i32)
12 declare void @C()
13
14 define void @indbrtest0(i8** %P, i8** %Q) {
15 entry:
16   store i8* blockaddress(@indbrtest0, %BB0), i8** %P
17   store i8* blockaddress(@indbrtest0, %BB1), i8** %P
18   store i8* blockaddress(@indbrtest0, %BB2), i8** %P
19   call void @foo()
20   %t = load i8** %Q
21   indirectbr i8* %t, [label %BB0, label %BB1, label %BB2, label %BB0, label %BB1, label %BB2]
22 BB0:
23   call void @A()
24   br label %BB1
25 BB1:
26   %x = phi i32 [ 0, %BB0 ], [ 1, %entry ], [ 1, %entry ]
27   call void @B(i32 %x)
28   ret void
29 BB2:
30   call void @C()
31   ret void
32 }
33
34 ; SimplifyCFG should convert the indirectbr into a directbr. It would be even
35 ; better if it removed the branch altogether, but simplifycfdg currently misses
36 ; that because the predecessor is the entry block.
37
38 ; CHECK: indbrtest1
39 ; CHECK: br label %BB0
40
41 define void @indbrtest1(i8** %P, i8** %Q) {
42 entry:
43   store i8* blockaddress(@indbrtest1, %BB0), i8** %P
44   call void @foo()
45   %t = load i8** %Q
46   indirectbr i8* %t, [label %BB0, label %BB0]
47 BB0:
48   call void @A()
49   ret void
50 }
51
52 ; SimplifyCFG should notice that BB0 does not have its address taken and
53 ; remove it from entry's successor list.
54
55 ; CHECK: indbrtest2
56 ; CHECK: entry:
57 ; CHECK-NEXT: unreachable
58
59 define void @indbrtest2(i8* %t) {
60 entry:
61   indirectbr i8* %t, [label %BB0, label %BB0]
62 BB0:
63   ret void
64 }
65
66
67 ; Make sure the blocks in the next few tests aren't trivially removable as
68 ; successors by taking their addresses.
69
70 @anchor = constant [13 x i8*] [
71   i8* blockaddress(@indbrtest3, %L1), i8* blockaddress(@indbrtest3, %L2), i8* blockaddress(@indbrtest3, %L3),
72   i8* blockaddress(@indbrtest4, %L1), i8* blockaddress(@indbrtest4, %L2), i8* blockaddress(@indbrtest4, %L3),
73   i8* blockaddress(@indbrtest5, %L1), i8* blockaddress(@indbrtest5, %L2), i8* blockaddress(@indbrtest5, %L3), i8* blockaddress(@indbrtest5, %L4),
74   i8* blockaddress(@indbrtest6, %L1), i8* blockaddress(@indbrtest6, %L2), i8* blockaddress(@indbrtest6, %L3)
75 ]
76
77 ; SimplifyCFG should turn the indirectbr into a conditional branch on the
78 ; condition of the select.
79
80 ; CHECK-LABEL: @indbrtest3(
81 ; CHECK-NEXT: entry:
82 ; CHECK-NEXT: br i1 %cond, label %L1, label %L2
83 ; CHECK-NOT: indirectbr
84 ; CHECK-NOT: br
85 ; CHECK-NOT: L3:
86 define void @indbrtest3(i1 %cond, i8* %address) nounwind {
87 entry:
88   %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest3, %L1), i8* blockaddress(@indbrtest3, %L2)
89   indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3]
90
91 L1:
92   call void @A()
93   ret void
94 L2:
95   call void @C()
96   ret void
97 L3:
98   call void @foo()
99   ret void
100 }
101
102 ; SimplifyCFG should turn the indirectbr into an unconditional branch to the
103 ; only possible destination.
104 ; As in @indbrtest1, it should really remove the branch entirely, but it doesn't
105 ; because it's in the entry block.
106
107 ; CHECK-LABEL: @indbrtest4(
108 ; CHECK-NEXT: entry:
109 ; CHECK-NEXT: br label %L1
110 define void @indbrtest4(i1 %cond) nounwind {
111 entry:
112   %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest4, %L1), i8* blockaddress(@indbrtest4, %L1)
113   indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3]
114
115 L1:
116   call void @A()
117   ret void
118 L2:
119   call void @C()
120   ret void
121 L3:
122   call void @foo()
123   ret void
124 }
125
126 ; SimplifyCFG should turn the indirectbr into an unreachable because neither
127 ; destination is listed as a successor.
128
129 ; CHECK-LABEL: @indbrtest5(
130 ; CHECK-NEXT: entry:
131 ; CHECK-NEXT: unreachable
132 ; CHECK-NEXT: }
133 define void @indbrtest5(i1 %cond, i8* %anchor) nounwind {
134 entry:
135   %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest5, %L1), i8* blockaddress(@indbrtest5, %L2)
136 ; This needs to have more than one successor for this test, otherwise it gets
137 ; replaced with an unconditional branch to the single successor.
138   indirectbr i8* %indirect.goto.dest, [label %L3, label %L4]
139
140 L1:
141   call void @A()
142   ret void
143 L2:
144   call void @C()
145   ret void
146 L3:
147   call void @foo()
148   ret void
149 L4:
150   call void @foo()
151
152 ; This keeps blockaddresses not otherwise listed as successors from being zapped
153 ; before SimplifyCFG even looks at the indirectbr.
154   indirectbr i8* %anchor, [label %L1, label %L2]
155 }
156
157 ; The same as above, except the selected addresses are equal.
158
159 ; CHECK-LABEL: @indbrtest6(
160 ; CHECK-NEXT: entry:
161 ; CHECK-NEXT: unreachable
162 ; CHECK-NEXT: }
163 define void @indbrtest6(i1 %cond, i8* %anchor) nounwind {
164 entry:
165   %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest6, %L1), i8* blockaddress(@indbrtest6, %L1)
166 ; This needs to have more than one successor for this test, otherwise it gets
167 ; replaced with an unconditional branch to the single successor.
168   indirectbr i8* %indirect.goto.dest, [label %L2, label %L3]
169
170 L1:
171   call void @A()
172   ret void
173 L2:
174   call void @C()
175   ret void
176 L3:
177   call void @foo()
178
179 ; This keeps blockaddresses not otherwise listed as successors from being zapped
180 ; before SimplifyCFG even looks at the indirectbr.
181   indirectbr i8* %anchor, [label %L1, label %L2]
182 }
183
184 ; PR10072
185
186 @xblkx.bbs = internal unnamed_addr constant [9 x i8*] [i8* blockaddress(@indbrtest7, %xblkx.begin), i8* blockaddress(@indbrtest7, %xblkx.begin3), i8* blockaddress(@indbrtest7, %xblkx.begin4), i8* blockaddress(@indbrtest7, %xblkx.begin5), i8* blockaddress(@indbrtest7, %xblkx.begin6), i8* blockaddress(@indbrtest7, %xblkx.begin7), i8* blockaddress(@indbrtest7, %xblkx.begin8), i8* blockaddress(@indbrtest7, %xblkx.begin9), i8* blockaddress(@indbrtest7, %xblkx.end)]
187
188 define void @indbrtest7() {
189 escape-string.top:
190   %xval202x = call i32 @xfunc5x()
191   br label %xlab5x
192
193 xlab8x:                                           ; preds = %xlab5x
194   %xvaluex = call i32 @xselectorx()
195   %xblkx.x = getelementptr [9 x i8*]* @xblkx.bbs, i32 0, i32 %xvaluex
196   %xblkx.load = load i8** %xblkx.x
197   indirectbr i8* %xblkx.load, [label %xblkx.begin, label %xblkx.begin3, label %xblkx.begin4, label %xblkx.begin5, label %xblkx.begin6, label %xblkx.begin7, label %xblkx.begin8, label %xblkx.begin9, label %xblkx.end]
198
199 xblkx.begin:
200   br label %xblkx.end
201
202 xblkx.begin3:
203   br label %xblkx.end
204
205 xblkx.begin4:
206   br label %xblkx.end
207
208 xblkx.begin5:
209   br label %xblkx.end
210
211 xblkx.begin6:
212   br label %xblkx.end
213
214 xblkx.begin7:
215   br label %xblkx.end
216
217 xblkx.begin8:
218   br label %xblkx.end
219
220 xblkx.begin9:
221   br label %xblkx.end
222
223 xblkx.end:
224   %yes.0 = phi i1 [ false, %xblkx.begin ], [ true, %xlab8x ], [ false, %xblkx.begin9 ], [ false, %xblkx.begin8 ], [ false, %xblkx.begin7 ], [ false, %xblkx.begin6 ], [ false, %xblkx.begin5 ], [ true, %xblkx.begin4 ], [ false, %xblkx.begin3 ]
225   br i1 %yes.0, label %v2j, label %xlab17x
226
227 v2j:
228 ; CHECK: %xunusedx = call i32 @xactionx()
229   %xunusedx = call i32 @xactionx()
230   br label %xlab4x
231
232 xlab17x:
233   br label %xlab4x
234
235 xlab4x:
236   %incr19 = add i32 %xval704x.0, 1
237   br label %xlab5x
238
239 xlab5x:
240   %xval704x.0 = phi i32 [ 0, %escape-string.top ], [ %incr19, %xlab4x ]
241   %xval10x = icmp ult i32 %xval704x.0, %xval202x
242   br i1 %xval10x, label %xlab8x, label %xlab9x
243
244 xlab9x:
245   ret void
246 }
247
248 declare i32 @xfunc5x()
249 declare i8 @xfunc7x()
250 declare i32 @xselectorx()
251 declare i32 @xactionx()