1 ; RUN: opt < %s -simplifycfg -S | FileCheck %s
8 define void @test1(i32 %V) {
9 %C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1]
10 %C2 = icmp eq i32 %V, 17 ; <i1> [#uses=1]
11 %CN = or i1 %C1, %C2 ; <i1> [#uses=1]
12 br i1 %CN, label %T, label %F
20 ; CHECK: switch i32 %V, label %F [
21 ; CHECK: i32 17, label %T
22 ; CHECK: i32 4, label %T
26 define void @test2(i32 %V) {
27 %C1 = icmp ne i32 %V, 4 ; <i1> [#uses=1]
28 %C2 = icmp ne i32 %V, 17 ; <i1> [#uses=1]
29 %CN = and i1 %C1, %C2 ; <i1> [#uses=1]
30 br i1 %CN, label %T, label %F
38 ; CHECK: switch i32 %V, label %T [
39 ; CHECK: i32 17, label %F
40 ; CHECK: i32 4, label %F
44 define void @test3(i32 %V) {
45 %C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1]
46 br i1 %C1, label %T, label %N
48 %C2 = icmp eq i32 %V, 17 ; <i1> [#uses=1]
49 br i1 %C2, label %T, label %F
58 ; CHECK: switch i32 %V, label %F [
59 ; CHECK: i32 4, label %T
60 ; CHECK: i32 17, label %T
66 define i32 @test4(i8 zeroext %c) nounwind ssp noredzone {
68 %cmp = icmp eq i8 %c, 62
69 br i1 %cmp, label %lor.end, label %lor.lhs.false
71 lor.lhs.false: ; preds = %entry
72 %cmp4 = icmp eq i8 %c, 34
73 br i1 %cmp4, label %lor.end, label %lor.rhs
75 lor.rhs: ; preds = %lor.lhs.false
76 %cmp8 = icmp eq i8 %c, 92
79 lor.end: ; preds = %lor.rhs, %lor.lhs.false, %entry
80 %0 = phi i1 [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp8, %lor.rhs ]
81 %lor.ext = zext i1 %0 to i32
85 ; CHECK: switch i8 %c, label %lor.rhs [
86 ; CHECK: i8 62, label %lor.end
87 ; CHECK: i8 34, label %lor.end
88 ; CHECK: i8 92, label %lor.end
92 define i32 @test5(i8 zeroext %c) nounwind ssp noredzone {
94 switch i8 %c, label %lor.rhs [
100 lor.rhs: ; preds = %entry
101 %V = icmp eq i8 %c, 92
104 lor.end: ; preds = %entry, %entry, %entry, %lor.rhs
105 %0 = phi i1 [ true, %entry ], [ %V, %lor.rhs ], [ true, %entry ], [ true, %entry ]
106 %lor.ext = zext i1 %0 to i32
109 ; CHECK: switch i8 %c, label %lor.rhs [
110 ; CHECK: i8 62, label %lor.end
111 ; CHECK: i8 34, label %lor.end
112 ; CHECK: i8 92, label %lor.end
117 define i1 @test6({ i32, i32 }* %I) {
119 %tmp.1.i = getelementptr { i32, i32 }* %I, i64 0, i32 1 ; <i32*> [#uses=1]
120 %tmp.2.i = load i32* %tmp.1.i ; <i32> [#uses=6]
121 %tmp.2 = icmp eq i32 %tmp.2.i, 14 ; <i1> [#uses=1]
122 br i1 %tmp.2, label %shortcirc_done.4, label %shortcirc_next.0
123 shortcirc_next.0: ; preds = %entry
124 %tmp.6 = icmp eq i32 %tmp.2.i, 15 ; <i1> [#uses=1]
125 br i1 %tmp.6, label %shortcirc_done.4, label %shortcirc_next.1
126 shortcirc_next.1: ; preds = %shortcirc_next.0
127 %tmp.11 = icmp eq i32 %tmp.2.i, 16 ; <i1> [#uses=1]
128 br i1 %tmp.11, label %shortcirc_done.4, label %shortcirc_next.2
129 shortcirc_next.2: ; preds = %shortcirc_next.1
130 %tmp.16 = icmp eq i32 %tmp.2.i, 17 ; <i1> [#uses=1]
131 br i1 %tmp.16, label %shortcirc_done.4, label %shortcirc_next.3
132 shortcirc_next.3: ; preds = %shortcirc_next.2
133 %tmp.21 = icmp eq i32 %tmp.2.i, 18 ; <i1> [#uses=1]
134 br i1 %tmp.21, label %shortcirc_done.4, label %shortcirc_next.4
135 shortcirc_next.4: ; preds = %shortcirc_next.3
136 %tmp.26 = icmp eq i32 %tmp.2.i, 19 ; <i1> [#uses=1]
137 br label %UnifiedReturnBlock
138 shortcirc_done.4: ; preds = %shortcirc_next.3, %shortcirc_next.2, %shortcirc_next.1, %shortcirc_next.0, %entry
139 br label %UnifiedReturnBlock
140 UnifiedReturnBlock: ; preds = %shortcirc_done.4, %shortcirc_next.4
141 %UnifiedRetVal = phi i1 [ %tmp.26, %shortcirc_next.4 ], [ true, %shortcirc_done.4 ] ; <i1> [#uses=1]
142 ret i1 %UnifiedRetVal
145 ; CHECK: switch i32 %tmp.2.i, label %shortcirc_next.4 [
146 ; CHECK: i32 14, label %UnifiedReturnBlock
147 ; CHECK: i32 15, label %UnifiedReturnBlock
148 ; CHECK: i32 16, label %UnifiedReturnBlock
149 ; CHECK: i32 17, label %UnifiedReturnBlock
150 ; CHECK: i32 18, label %UnifiedReturnBlock
151 ; CHECK: i32 19, label %switch.edge
155 define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone {
157 %cmp = icmp ult i32 %x, 32
158 %cmp4 = icmp eq i8 %c, 97
159 %or.cond = or i1 %cmp, %cmp4
160 %cmp9 = icmp eq i8 %c, 99
161 %or.cond11 = or i1 %or.cond, %cmp9
162 br i1 %or.cond11, label %if.then, label %if.end
164 if.then: ; preds = %entry
165 tail call void @foo1() nounwind noredzone
168 if.end: ; preds = %entry
172 ; CHECK: %cmp = icmp ult i32 %x, 32
173 ; CHECK: br i1 %cmp, label %if.then, label %switch.early.test
174 ; CHECK: switch.early.test:
175 ; CHECK: switch i8 %c, label %if.end [
176 ; CHECK: i8 99, label %if.then
177 ; CHECK: i8 97, label %if.then
181 define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone {
183 br i1 %C, label %N, label %if.then
185 %cmp = icmp ult i32 %x, 32
186 %cmp4 = icmp eq i8 %c, 97
187 %or.cond = or i1 %cmp, %cmp4
188 %cmp9 = icmp eq i8 %c, 99
189 %or.cond11 = or i1 %or.cond, %cmp9
190 br i1 %or.cond11, label %if.then, label %if.end
192 if.then: ; preds = %entry
193 %A = phi i32 [0, %entry], [42, %N]
194 tail call void @foo1() nounwind noredzone
197 if.end: ; preds = %entry
201 ; CHECK: switch.early.test:
202 ; CHECK: switch i8 %c, label %if.end [
203 ; CHECK: i8 99, label %if.then
204 ; CHECK: i8 97, label %if.then
206 ; CHECK: %A = phi i32 [ 0, %entry ], [ 42, %switch.early.test ], [ 42, %N ], [ 42, %switch.early.test ]
209 ;; This is "Example 7" from http://blog.regehr.org/archives/320
210 define i32 @test9(i8 zeroext %c) nounwind ssp noredzone {
212 %cmp = icmp ult i8 %c, 33
213 br i1 %cmp, label %lor.end, label %lor.lhs.false
215 lor.lhs.false: ; preds = %entry
216 %cmp4 = icmp eq i8 %c, 46
217 br i1 %cmp4, label %lor.end, label %lor.lhs.false6
219 lor.lhs.false6: ; preds = %lor.lhs.false
220 %cmp9 = icmp eq i8 %c, 44
221 br i1 %cmp9, label %lor.end, label %lor.lhs.false11
223 lor.lhs.false11: ; preds = %lor.lhs.false6
224 %cmp14 = icmp eq i8 %c, 58
225 br i1 %cmp14, label %lor.end, label %lor.lhs.false16
227 lor.lhs.false16: ; preds = %lor.lhs.false11
228 %cmp19 = icmp eq i8 %c, 59
229 br i1 %cmp19, label %lor.end, label %lor.lhs.false21
231 lor.lhs.false21: ; preds = %lor.lhs.false16
232 %cmp24 = icmp eq i8 %c, 60
233 br i1 %cmp24, label %lor.end, label %lor.lhs.false26
235 lor.lhs.false26: ; preds = %lor.lhs.false21
236 %cmp29 = icmp eq i8 %c, 62
237 br i1 %cmp29, label %lor.end, label %lor.lhs.false31
239 lor.lhs.false31: ; preds = %lor.lhs.false26
240 %cmp34 = icmp eq i8 %c, 34
241 br i1 %cmp34, label %lor.end, label %lor.lhs.false36
243 lor.lhs.false36: ; preds = %lor.lhs.false31
244 %cmp39 = icmp eq i8 %c, 92
245 br i1 %cmp39, label %lor.end, label %lor.rhs
247 lor.rhs: ; preds = %lor.lhs.false36
248 %cmp43 = icmp eq i8 %c, 39
251 lor.end: ; preds = %lor.rhs, %lor.lhs.false36, %lor.lhs.false31, %lor.lhs.false26, %lor.lhs.false21, %lor.lhs.false16, %lor.lhs.false11, %lor.lhs.false6, %lor.lhs.false, %entry
252 %0 = phi i1 [ true, %lor.lhs.false36 ], [ true, %lor.lhs.false31 ], [ true, %lor.lhs.false26 ], [ true, %lor.lhs.false21 ], [ true, %lor.lhs.false16 ], [ true, %lor.lhs.false11 ], [ true, %lor.lhs.false6 ], [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp43, %lor.rhs ]
253 %conv46 = zext i1 %0 to i32
257 ; HECK: %cmp = icmp ult i8 %c, 33
258 ; HECK: br i1 %cmp, label %lor.end, label %switch.early.test
260 ; HECK: switch.early.test:
261 ; HECK: switch i8 %c, label %lor.rhs [
262 ; HECK: i8 46, label %lor.end
263 ; HECK: i8 44, label %lor.end
264 ; HECK: i8 58, label %lor.end
265 ; HECK: i8 59, label %lor.end
266 ; HECK: i8 60, label %lor.end
267 ; HECK: i8 62, label %lor.end
268 ; HECK: i8 34, label %lor.end
269 ; HECK: i8 92, label %lor.end
270 ; HECK: i8 39, label %lor.end
274 define i32 @test10(i32 %mode, i1 %Cond) {
275 %A = icmp ne i32 %mode, 0
276 %B = icmp ne i32 %mode, 51
278 %D = and i1 %C, %Cond
279 br i1 %D, label %T, label %F
286 ; CHECK: br i1 %Cond, label %switch.early.test, label %F
287 ; CHECK:switch.early.test:
288 ; CHECK: switch i32 %mode, label %T [
289 ; CHECK: i32 51, label %F
290 ; CHECK: i32 0, label %F
295 define i32 @test11(i32 %bar) nounwind {
297 %cmp = icmp eq i32 %bar, 4
298 %cmp2 = icmp eq i32 %bar, 35
299 %or.cond = or i1 %cmp, %cmp2
300 %cmp5 = icmp eq i32 %bar, 53
301 %or.cond1 = or i1 %or.cond, %cmp5
302 %cmp8 = icmp eq i32 %bar, 24
303 %or.cond2 = or i1 %or.cond1, %cmp8
304 %cmp11 = icmp eq i32 %bar, 23
305 %or.cond3 = or i1 %or.cond2, %cmp11
306 %cmp14 = icmp eq i32 %bar, 55
307 %or.cond4 = or i1 %or.cond3, %cmp14
308 %cmp17 = icmp eq i32 %bar, 12
309 %or.cond5 = or i1 %or.cond4, %cmp17
310 %cmp20 = icmp eq i32 %bar, 35
311 %or.cond6 = or i1 %or.cond5, %cmp20
312 br i1 %or.cond6, label %if.then, label %if.end
314 if.then: ; preds = %entry
317 if.end: ; preds = %entry
320 return: ; preds = %if.end, %if.then
321 %retval.0 = phi i32 [ 1, %if.then ], [ 0, %if.end ]
325 ; CHECK: switch i32 %bar, label %if.end [
326 ; CHECK: i32 55, label %return
327 ; CHECK: i32 53, label %return
328 ; CHECK: i32 35, label %return
329 ; CHECK: i32 24, label %return
330 ; CHECK: i32 23, label %return
331 ; CHECK: i32 12, label %return
332 ; CHECK: i32 4, label %return
336 define void @test12() nounwind {
341 %A = icmp eq i32 undef, undef
342 br i1 %A, label %bb55.us.us, label %malformed
345 %B = icmp ugt i32 undef, undef
346 br i1 %B, label %bb55.us.us, label %bb49.us.us