4e199bc85964bdb9f62a15207f0e8e337495c5da
[oota-llvm.git] / test / Transforms / SimplifyCFG / switch_create.ll
1 ; RUN: opt < %s -simplifycfg -S | FileCheck %s
2
3 declare void @foo1()
4
5 declare void @foo2()
6
7 define void @test1(i32 %V) {
8         %C1 = icmp eq i32 %V, 4         ; <i1> [#uses=1]
9         %C2 = icmp eq i32 %V, 17                ; <i1> [#uses=1]
10         %CN = or i1 %C1, %C2            ; <i1> [#uses=1]
11         br i1 %CN, label %T, label %F
12 T:              ; preds = %0
13         call void @foo1( )
14         ret void
15 F:              ; preds = %0
16         call void @foo2( )
17         ret void
18 ; CHECK: @test1
19 ; CHECK:  switch i32 %V, label %F [
20 ; CHECK:    i32 17, label %T
21 ; CHECK:    i32 4, label %T
22 ; CHECK:  ]
23 }
24
25 define void @test2(i32 %V) {
26         %C1 = icmp ne i32 %V, 4         ; <i1> [#uses=1]
27         %C2 = icmp ne i32 %V, 17                ; <i1> [#uses=1]
28         %CN = and i1 %C1, %C2           ; <i1> [#uses=1]
29         br i1 %CN, label %T, label %F
30 T:              ; preds = %0
31         call void @foo1( )
32         ret void
33 F:              ; preds = %0
34         call void @foo2( )
35         ret void
36 ; CHECK: @test2
37 ; CHECK:  switch i32 %V, label %T [
38 ; CHECK:    i32 17, label %F
39 ; CHECK:    i32 4, label %F
40 ; CHECK:  ]
41 }
42
43 define void @test3(i32 %V) {
44         %C1 = icmp eq i32 %V, 4         ; <i1> [#uses=1]
45         br i1 %C1, label %T, label %N
46 N:              ; preds = %0
47         %C2 = icmp eq i32 %V, 17                ; <i1> [#uses=1]
48         br i1 %C2, label %T, label %F
49 T:              ; preds = %N, %0
50         call void @foo1( )
51         ret void
52 F:              ; preds = %N
53         call void @foo2( )
54         ret void
55
56 ; CHECK: @test3
57 ; CHECK: switch i32 %V, label %F [
58 ; CHECK:     i32 4, label %T
59 ; CHECK:     i32 17, label %T
60 ; CHECK:   ]
61 }
62
63
64
65 define i32 @test4(i8 zeroext %c) nounwind ssp noredzone {
66 entry:
67   %cmp = icmp eq i8 %c, 62
68   br i1 %cmp, label %lor.end, label %lor.lhs.false
69
70 lor.lhs.false:                                    ; preds = %entry
71   %cmp4 = icmp eq i8 %c, 34
72   br i1 %cmp4, label %lor.end, label %lor.rhs
73
74 lor.rhs:                                          ; preds = %lor.lhs.false
75   %cmp8 = icmp eq i8 %c, 92
76   br label %lor.end
77
78 lor.end:                                          ; preds = %lor.rhs, %lor.lhs.false, %entry
79   %0 = phi i1 [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp8, %lor.rhs ]
80   %lor.ext = zext i1 %0 to i32
81   ret i32 %lor.ext
82   
83 ; CHECK: @test4
84 ; CHECK:  switch i8 %c, label %lor.rhs [
85 ; CHECK:    i8 62, label %lor.end
86 ; CHECK:    i8 34, label %lor.end
87 ; CHECK:    i8 92, label %lor.end
88 ; CHECK:  ]
89 }
90
91 define i32 @test5(i8 zeroext %c) nounwind ssp noredzone {
92 entry:
93   switch i8 %c, label %lor.rhs [
94     i8 62, label %lor.end
95     i8 34, label %lor.end
96     i8 92, label %lor.end
97   ]
98
99 lor.rhs:                                          ; preds = %entry
100   %V = icmp eq i8 %c, 92
101   br label %lor.end
102
103 lor.end:                                          ; preds = %entry, %entry, %entry, %lor.rhs
104   %0 = phi i1 [ true, %entry ], [ %V, %lor.rhs ], [ true, %entry ], [ true, %entry ]
105   %lor.ext = zext i1 %0 to i32
106   ret i32 %lor.ext
107 ; CHECK: @test5
108 ; CHECK:  switch i8 %c, label %lor.rhs [
109 ; CHECK:    i8 62, label %lor.end
110 ; CHECK:    i8 34, label %lor.end
111 ; CHECK:    i8 92, label %lor.end
112 ; CHECK:  ]
113 }
114
115
116 define i1 @test6({ i32, i32 }* %I) {
117 entry:
118         %tmp.1.i = getelementptr { i32, i32 }* %I, i64 0, i32 1         ; <i32*> [#uses=1]
119         %tmp.2.i = load i32* %tmp.1.i           ; <i32> [#uses=6]
120         %tmp.2 = icmp eq i32 %tmp.2.i, 14               ; <i1> [#uses=1]
121         br i1 %tmp.2, label %shortcirc_done.4, label %shortcirc_next.0
122 shortcirc_next.0:               ; preds = %entry
123         %tmp.6 = icmp eq i32 %tmp.2.i, 15               ; <i1> [#uses=1]
124         br i1 %tmp.6, label %shortcirc_done.4, label %shortcirc_next.1
125 shortcirc_next.1:               ; preds = %shortcirc_next.0
126         %tmp.11 = icmp eq i32 %tmp.2.i, 16              ; <i1> [#uses=1]
127         br i1 %tmp.11, label %shortcirc_done.4, label %shortcirc_next.2
128 shortcirc_next.2:               ; preds = %shortcirc_next.1
129         %tmp.16 = icmp eq i32 %tmp.2.i, 17              ; <i1> [#uses=1]
130         br i1 %tmp.16, label %shortcirc_done.4, label %shortcirc_next.3
131 shortcirc_next.3:               ; preds = %shortcirc_next.2
132         %tmp.21 = icmp eq i32 %tmp.2.i, 18              ; <i1> [#uses=1]
133         br i1 %tmp.21, label %shortcirc_done.4, label %shortcirc_next.4
134 shortcirc_next.4:               ; preds = %shortcirc_next.3
135         %tmp.26 = icmp eq i32 %tmp.2.i, 19              ; <i1> [#uses=1]
136         br label %UnifiedReturnBlock
137 shortcirc_done.4:               ; preds = %shortcirc_next.3, %shortcirc_next.2, %shortcirc_next.1, %shortcirc_next.0, %entry
138         br label %UnifiedReturnBlock
139 UnifiedReturnBlock:             ; preds = %shortcirc_done.4, %shortcirc_next.4
140         %UnifiedRetVal = phi i1 [ %tmp.26, %shortcirc_next.4 ], [ true, %shortcirc_done.4 ]             ; <i1> [#uses=1]
141         ret i1 %UnifiedRetVal
142         
143 ; CHECK: @test6
144 ; CHECK:   switch i32 %tmp.2.i, label %shortcirc_next.4 [
145 ; CHECK:       i32 14, label %UnifiedReturnBlock
146 ; CHECK:       i32 15, label %UnifiedReturnBlock
147 ; CHECK:       i32 16, label %UnifiedReturnBlock
148 ; CHECK:       i32 17, label %UnifiedReturnBlock
149 ; CHECK:       i32 18, label %UnifiedReturnBlock
150 ; CHECK:       i32 19, label %UnifiedReturnBlock
151 ; CHECK:     ]
152 }
153
154 define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone {
155 entry:
156   %cmp = icmp ult i32 %x, 32
157   %cmp4 = icmp eq i8 %c, 97
158   %or.cond = or i1 %cmp, %cmp4
159   %cmp9 = icmp eq i8 %c, 99
160   %or.cond11 = or i1 %or.cond, %cmp9
161   br i1 %or.cond11, label %if.then, label %if.end
162
163 if.then:                                          ; preds = %entry
164   tail call void @foo1() nounwind noredzone
165   ret void
166
167 if.end:                                           ; preds = %entry
168   ret void
169   
170 ; CHECK: @test7
171 ; CHECK:   %cmp = icmp ult i32 %x, 32
172 ; CHECK:   br i1 %cmp, label %if.then, label %switch.early.test
173 ; CHECK: switch.early.test:
174 ; CHECK:   switch i8 %c, label %if.end [
175 ; CHECK:     i8 99, label %if.then
176 ; CHECK:     i8 97, label %if.then
177 ; CHECK:   ]
178 }
179
180 define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone {
181 entry:
182   br i1 %C, label %N, label %if.then
183 N:
184   %cmp = icmp ult i32 %x, 32
185   %cmp4 = icmp eq i8 %c, 97
186   %or.cond = or i1 %cmp, %cmp4
187   %cmp9 = icmp eq i8 %c, 99
188   %or.cond11 = or i1 %or.cond, %cmp9
189   br i1 %or.cond11, label %if.then, label %if.end
190
191 if.then:                                          ; preds = %entry
192   %A = phi i32 [0, %entry], [42, %N]
193   tail call void @foo1() nounwind noredzone
194   ret i32 %A
195
196 if.end:                                           ; preds = %entry
197   ret i32 0
198   
199 ; CHECK: @test8
200 ; CHECK: switch.early.test:
201 ; CHECK:   switch i8 %c, label %if.end [
202 ; CHECK:     i8 99, label %if.then
203 ; CHECK:     i8 97, label %if.then
204 ; CHECK:   ]
205 ; CHECK:   %A = phi i32 [ 0, %entry ], [ 42, %switch.early.test ], [ 42, %N ], [ 42, %switch.early.test ]
206 }
207
208 ;; This is "Example 7" from http://blog.regehr.org/archives/320
209 define i32 @test9(i8 zeroext %c) nounwind ssp noredzone {
210 entry:
211   %cmp = icmp ult i8 %c, 33
212   br i1 %cmp, label %lor.end, label %lor.lhs.false
213
214 lor.lhs.false:                                    ; preds = %entry
215   %cmp4 = icmp eq i8 %c, 46
216   br i1 %cmp4, label %lor.end, label %lor.lhs.false6
217
218 lor.lhs.false6:                                   ; preds = %lor.lhs.false
219   %cmp9 = icmp eq i8 %c, 44
220   br i1 %cmp9, label %lor.end, label %lor.lhs.false11
221
222 lor.lhs.false11:                                  ; preds = %lor.lhs.false6
223   %cmp14 = icmp eq i8 %c, 58
224   br i1 %cmp14, label %lor.end, label %lor.lhs.false16
225
226 lor.lhs.false16:                                  ; preds = %lor.lhs.false11
227   %cmp19 = icmp eq i8 %c, 59
228   br i1 %cmp19, label %lor.end, label %lor.lhs.false21
229
230 lor.lhs.false21:                                  ; preds = %lor.lhs.false16
231   %cmp24 = icmp eq i8 %c, 60
232   br i1 %cmp24, label %lor.end, label %lor.lhs.false26
233
234 lor.lhs.false26:                                  ; preds = %lor.lhs.false21
235   %cmp29 = icmp eq i8 %c, 62
236   br i1 %cmp29, label %lor.end, label %lor.lhs.false31
237
238 lor.lhs.false31:                                  ; preds = %lor.lhs.false26
239   %cmp34 = icmp eq i8 %c, 34
240   br i1 %cmp34, label %lor.end, label %lor.lhs.false36
241
242 lor.lhs.false36:                                  ; preds = %lor.lhs.false31
243   %cmp39 = icmp eq i8 %c, 92
244   br i1 %cmp39, label %lor.end, label %lor.rhs
245
246 lor.rhs:                                          ; preds = %lor.lhs.false36
247   %cmp43 = icmp eq i8 %c, 39
248   br label %lor.end
249
250 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
251   %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 ]
252   %conv46 = zext i1 %0 to i32
253   ret i32 %conv46
254   
255 ; CHECK: @test9
256 ; CHECK:   %cmp = icmp ult i8 %c, 33
257 ; CHECK:   br i1 %cmp, label %lor.end, label %switch.early.test
258
259 ; CHECK: switch.early.test:
260 ; CHECK:   switch i8 %c, label %lor.rhs [
261 ; CHECK:     i8 92, label %lor.end
262 ; CHECK:     i8 62, label %lor.end
263 ; CHECK:     i8 60, label %lor.end
264 ; CHECK:     i8 59, label %lor.end
265 ; CHECK:     i8 58, label %lor.end
266 ; CHECK:     i8 46, label %lor.end
267 ; CHECK:     i8 44, label %lor.end
268 ; CHECK:     i8 34, label %lor.end
269 ; CHECK:     i8 39, label %lor.end
270 ; CHECK:   ]
271 }
272
273 define i32 @test10(i32 %mode, i1 %Cond) {
274   %A = icmp ne i32 %mode, 0
275   %B = icmp ne i32 %mode, 51
276   %C = and i1 %A, %B
277   %D = and i1 %C, %Cond
278   br i1 %D, label %T, label %F
279 T:
280   ret i32 123
281 F:
282   ret i32 324
283
284 ; CHECK: @test10
285 ; CHECK:  br i1 %Cond, label %switch.early.test, label %F
286 ; CHECK:switch.early.test:
287 ; CHECK:  switch i32 %mode, label %T [
288 ; CHECK:    i32 51, label %F
289 ; CHECK:    i32 0, label %F
290 ; CHECK:  ]
291 }
292
293 ; PR8780
294 define i32 @test11(i32 %bar) nounwind {
295 entry:
296   %cmp = icmp eq i32 %bar, 4
297   %cmp2 = icmp eq i32 %bar, 35
298   %or.cond = or i1 %cmp, %cmp2
299   %cmp5 = icmp eq i32 %bar, 53
300   %or.cond1 = or i1 %or.cond, %cmp5
301   %cmp8 = icmp eq i32 %bar, 24
302   %or.cond2 = or i1 %or.cond1, %cmp8
303   %cmp11 = icmp eq i32 %bar, 23
304   %or.cond3 = or i1 %or.cond2, %cmp11
305   %cmp14 = icmp eq i32 %bar, 55
306   %or.cond4 = or i1 %or.cond3, %cmp14
307   %cmp17 = icmp eq i32 %bar, 12
308   %or.cond5 = or i1 %or.cond4, %cmp17
309   %cmp20 = icmp eq i32 %bar, 35
310   %or.cond6 = or i1 %or.cond5, %cmp20
311   br i1 %or.cond6, label %if.then, label %if.end
312
313 if.then:                                          ; preds = %entry
314   br label %return
315
316 if.end:                                           ; preds = %entry
317   br label %return
318
319 return:                                           ; preds = %if.end, %if.then
320   %retval.0 = phi i32 [ 1, %if.then ], [ 0, %if.end ]
321   ret i32 %retval.0
322
323 ; CHECK: @test11
324 ; CHECK: switch i32 %bar, label %if.end [
325 ; CHECK:   i32 55, label %return
326 ; CHECK:   i32 53, label %return
327 ; CHECK:   i32 35, label %return
328 ; CHECK:   i32 24, label %return
329 ; CHECK:   i32 23, label %return
330 ; CHECK:   i32 12, label %return
331 ; CHECK:   i32 4, label %return
332 ; CHECK: ]
333 }
334
335 define void @test12() nounwind {
336 entry:
337   br label %bb49.us.us
338
339 bb49.us.us:
340   %A = icmp eq i32 undef, undef
341   br i1 %A, label %bb55.us.us, label %malformed
342
343 bb48.us.us:
344   %B = icmp ugt i32 undef, undef
345   br i1 %B, label %bb55.us.us, label %bb49.us.us
346
347 bb55.us.us:
348   br label %bb48.us.us
349
350 malformed:
351   ret void
352 ; CHECK: @test12
353
354 }
355
356 ; test13 - handle switch formation with ult.
357 define void @test13(i32 %x) nounwind ssp noredzone {
358 entry:
359   %cmp = icmp ult i32 %x, 2
360   br i1 %cmp, label %if.then, label %lor.lhs.false3
361
362 lor.lhs.false3:                                   ; preds = %lor.lhs.false
363   %cmp5 = icmp eq i32 %x, 3
364   br i1 %cmp5, label %if.then, label %lor.lhs.false6
365
366 lor.lhs.false6:                                   ; preds = %lor.lhs.false3
367   %cmp8 = icmp eq i32 %x, 4
368   br i1 %cmp8, label %if.then, label %lor.lhs.false9
369
370 lor.lhs.false9:                                   ; preds = %lor.lhs.false6
371   %cmp11 = icmp eq i32 %x, 6
372   br i1 %cmp11, label %if.then, label %if.end
373
374 if.then:                                          ; preds = %lor.lhs.false9, %lor.lhs.false6, %lor.lhs.false3, %lor.lhs.false, %entry
375   call void @foo1() noredzone
376   br label %if.end
377
378 if.end:                                           ; preds = %if.then, %lor.lhs.false9
379   ret void
380 ; CHECK: @test13
381 ; CHECK:  switch i32 %x, label %if.end [
382 ; CHECK:     i32 6, label %if.then
383 ; CHECK:     i32 4, label %if.then
384 ; CHECK:     i32 3, label %if.then
385 ; CHECK:     i32 1, label %if.then
386 ; CHECK:     i32 0, label %if.then
387 ; CHECK:   ]
388 }
389
390 ; test14 - handle switch formation with ult.
391 define void @test14(i32 %x) nounwind ssp noredzone {
392 entry:
393   %cmp = icmp ugt i32 %x, 2
394   br i1 %cmp, label %lor.lhs.false3, label %if.then
395
396 lor.lhs.false3:                                   ; preds = %lor.lhs.false
397   %cmp5 = icmp ne i32 %x, 3
398   br i1 %cmp5, label %lor.lhs.false6, label %if.then
399
400 lor.lhs.false6:                                   ; preds = %lor.lhs.false3
401   %cmp8 = icmp ne i32 %x, 4
402   br i1 %cmp8, label %lor.lhs.false9, label %if.then
403
404 lor.lhs.false9:                                   ; preds = %lor.lhs.false6
405   %cmp11 = icmp ne i32 %x, 6
406   br i1 %cmp11, label %if.end, label %if.then
407
408 if.then:                                          ; preds = %lor.lhs.false9, %lor.lhs.false6, %lor.lhs.false3, %lor.lhs.false, %entry
409   call void @foo1() noredzone
410   br label %if.end
411
412 if.end:                                           ; preds = %if.then, %lor.lhs.false9
413   ret void
414 ; CHECK: @test14
415 ; CHECK:  switch i32 %x, label %if.end [
416 ; CHECK:     i32 6, label %if.then
417 ; CHECK:     i32 4, label %if.then
418 ; CHECK:     i32 3, label %if.then
419 ; CHECK:     i32 1, label %if.then
420 ; CHECK:     i32 0, label %if.then
421 ; CHECK:   ]
422 }
423
424 ; Don't crash on ginormous ranges.
425 define void @test15(i128 %x) nounwind {
426   %cmp = icmp ugt i128 %x, 2
427   br i1 %cmp, label %if.end, label %lor.false
428
429 lor.false:
430   %cmp2 = icmp ne i128 %x, 100000000000000000000
431   br i1 %cmp2, label %if.end, label %if.then
432
433 if.then:
434   call void @foo1() noredzone
435   br label %if.end
436
437 if.end:
438   ret void
439
440 ; CHECK: @test15
441 ; CHECK-NOT: switch
442 ; CHECK: ret void
443 }
444
445 ; PR8675
446 ; rdar://5134905
447 define zeroext i1 @test16(i32 %x) nounwind {
448 entry:
449 ; CHECK: @test16
450 ; CHECK: switch i32 %x, label %lor.rhs [
451 ; CHECK:   i32 1, label %lor.end
452 ; CHECK:   i32 2, label %lor.end
453 ; CHECK:   i32 3, label %lor.end
454 ; CHECK: ]
455   %cmp.i = icmp eq i32 %x, 1
456   br i1 %cmp.i, label %lor.end, label %lor.lhs.false
457
458 lor.lhs.false:
459   %cmp.i2 = icmp eq i32 %x, 2
460   br i1 %cmp.i2, label %lor.end, label %lor.rhs
461
462 lor.rhs:
463   %cmp.i1 = icmp eq i32 %x, 3
464   br label %lor.end
465
466 lor.end:
467   %0 = phi i1 [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp.i1, %lor.rhs ]
468   ret i1 %0
469 }