[MIParser] Set RegClassOrRegBank during instruction parsing
[llvm-complete.git] / test / Transforms / SimplifyCFG / switch_create.ll
blob3314fc982ae77fe83097d30faef3c4677145fa0d
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -simplifycfg < %s | FileCheck %s
3 ; RUN: opt -S -data-layout="p:32:32-p1:16:16" -simplifycfg < %s | FileCheck -check-prefix=CHECK -check-prefix=DL %s
5 declare void @foo1()
7 declare void @foo2()
9 define void @test1(i32 %V) {
10 ; CHECK-LABEL: @test1(
11 ; CHECK-NEXT:    switch i32 [[V:%.*]], label [[F:%.*]] [
12 ; CHECK-NEXT:    i32 17, label [[T:%.*]]
13 ; CHECK-NEXT:    i32 4, label [[T]]
14 ; CHECK-NEXT:    ]
15 ; CHECK:       T:
16 ; CHECK-NEXT:    call void @foo1()
17 ; CHECK-NEXT:    ret void
18 ; CHECK:       F:
19 ; CHECK-NEXT:    call void @foo2()
20 ; CHECK-NEXT:    ret void
22   %C1 = icmp eq i32 %V, 4         ; <i1> [#uses=1]
23   %C2 = icmp eq i32 %V, 17                ; <i1> [#uses=1]
24   %CN = or i1 %C1, %C2            ; <i1> [#uses=1]
25   br i1 %CN, label %T, label %F
26 T:              ; preds = %0
27   call void @foo1( )
28   ret void
29 F:              ; preds = %0
30   call void @foo2( )
31   ret void
34 define void @test1_ptr(i32* %V) {
35 ; DL-LABEL: @test1_ptr(
36 ; DL-NEXT:    [[MAGICPTR:%.*]] = ptrtoint i32* [[V:%.*]] to i32
37 ; DL-NEXT:    switch i32 [[MAGICPTR]], label [[F:%.*]] [
38 ; DL-NEXT:    i32 17, label [[T:%.*]]
39 ; DL-NEXT:    i32 4, label [[T]]
40 ; DL-NEXT:    ]
41 ; DL:       T:
42 ; DL-NEXT:    call void @foo1()
43 ; DL-NEXT:    ret void
44 ; DL:       F:
45 ; DL-NEXT:    call void @foo2()
46 ; DL-NEXT:    ret void
48   %C1 = icmp eq i32* %V, inttoptr (i32 4 to i32*)
49   %C2 = icmp eq i32* %V, inttoptr (i32 17 to i32*)
50   %CN = or i1 %C1, %C2            ; <i1> [#uses=1]
51   br i1 %CN, label %T, label %F
52 T:              ; preds = %0
53   call void @foo1( )
54   ret void
55 F:              ; preds = %0
56   call void @foo2( )
57   ret void
60 define void @test1_ptr_as1(i32 addrspace(1)* %V) {
61 ; DL-LABEL: @test1_ptr_as1(
62 ; DL-NEXT:    [[MAGICPTR:%.*]] = ptrtoint i32 addrspace(1)* [[V:%.*]] to i16
63 ; DL-NEXT:    switch i16 [[MAGICPTR]], label [[F:%.*]] [
64 ; DL-NEXT:    i16 17, label [[T:%.*]]
65 ; DL-NEXT:    i16 4, label [[T]]
66 ; DL-NEXT:    ]
67 ; DL:       T:
68 ; DL-NEXT:    call void @foo1()
69 ; DL-NEXT:    ret void
70 ; DL:       F:
71 ; DL-NEXT:    call void @foo2()
72 ; DL-NEXT:    ret void
74   %C1 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 4 to i32 addrspace(1)*)
75   %C2 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 17 to i32 addrspace(1)*)
76   %CN = or i1 %C1, %C2            ; <i1> [#uses=1]
77   br i1 %CN, label %T, label %F
78 T:              ; preds = %0
79   call void @foo1( )
80   ret void
81 F:              ; preds = %0
82   call void @foo2( )
83   ret void
86 define void @test2(i32 %V) {
87 ; CHECK-LABEL: @test2(
88 ; CHECK-NEXT:    switch i32 [[V:%.*]], label [[T:%.*]] [
89 ; CHECK-NEXT:    i32 17, label [[F:%.*]]
90 ; CHECK-NEXT:    i32 4, label [[F]]
91 ; CHECK-NEXT:    ]
92 ; CHECK:       T:
93 ; CHECK-NEXT:    call void @foo1()
94 ; CHECK-NEXT:    ret void
95 ; CHECK:       F:
96 ; CHECK-NEXT:    call void @foo2()
97 ; CHECK-NEXT:    ret void
99   %C1 = icmp ne i32 %V, 4         ; <i1> [#uses=1]
100   %C2 = icmp ne i32 %V, 17                ; <i1> [#uses=1]
101   %CN = and i1 %C1, %C2           ; <i1> [#uses=1]
102   br i1 %CN, label %T, label %F
103 T:              ; preds = %0
104   call void @foo1( )
105   ret void
106 F:              ; preds = %0
107   call void @foo2( )
108   ret void
111 define void @test3(i32 %V) {
112 ; CHECK-LABEL: @test3(
113 ; CHECK-NEXT:    switch i32 [[V:%.*]], label [[F:%.*]] [
114 ; CHECK-NEXT:    i32 4, label [[T:%.*]]
115 ; CHECK-NEXT:    i32 17, label [[T]]
116 ; CHECK-NEXT:    ]
117 ; CHECK:       T:
118 ; CHECK-NEXT:    call void @foo1()
119 ; CHECK-NEXT:    ret void
120 ; CHECK:       F:
121 ; CHECK-NEXT:    call void @foo2()
122 ; CHECK-NEXT:    ret void
124   %C1 = icmp eq i32 %V, 4         ; <i1> [#uses=1]
125   br i1 %C1, label %T, label %N
126 N:              ; preds = %0
127   %C2 = icmp eq i32 %V, 17                ; <i1> [#uses=1]
128   br i1 %C2, label %T, label %F
129 T:              ; preds = %N, %0
130   call void @foo1( )
131   ret void
132 F:              ; preds = %N
133   call void @foo2( )
134   ret void
140 define i32 @test4(i8 zeroext %c) nounwind ssp noredzone {
141 ; CHECK-LABEL: @test4(
142 ; CHECK-NEXT:  entry:
143 ; CHECK-NEXT:    switch i8 [[C:%.*]], label [[LOR_RHS:%.*]] [
144 ; CHECK-NEXT:    i8 62, label [[LOR_END:%.*]]
145 ; CHECK-NEXT:    i8 34, label [[LOR_END]]
146 ; CHECK-NEXT:    i8 92, label [[LOR_END]]
147 ; CHECK-NEXT:    ]
148 ; CHECK:       lor.rhs:
149 ; CHECK-NEXT:    br label [[LOR_END]]
150 ; CHECK:       lor.end:
151 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ]
152 ; CHECK-NEXT:    [[LOR_EXT:%.*]] = zext i1 [[TMP0]] to i32
153 ; CHECK-NEXT:    ret i32 [[LOR_EXT]]
155 entry:
156   %cmp = icmp eq i8 %c, 62
157   br i1 %cmp, label %lor.end, label %lor.lhs.false
159 lor.lhs.false:                                    ; preds = %entry
160   %cmp4 = icmp eq i8 %c, 34
161   br i1 %cmp4, label %lor.end, label %lor.rhs
163 lor.rhs:                                          ; preds = %lor.lhs.false
164   %cmp8 = icmp eq i8 %c, 92
165   br label %lor.end
167 lor.end:                                          ; preds = %lor.rhs, %lor.lhs.false, %entry
168   %0 = phi i1 [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp8, %lor.rhs ]
169   %lor.ext = zext i1 %0 to i32
170   ret i32 %lor.ext
174 define i32 @test5(i8 zeroext %c) nounwind ssp noredzone {
175 ; CHECK-LABEL: @test5(
176 ; CHECK-NEXT:  entry:
177 ; CHECK-NEXT:    switch i8 [[C:%.*]], label [[LOR_RHS:%.*]] [
178 ; CHECK-NEXT:    i8 62, label [[LOR_END:%.*]]
179 ; CHECK-NEXT:    i8 34, label [[LOR_END]]
180 ; CHECK-NEXT:    i8 92, label [[LOR_END]]
181 ; CHECK-NEXT:    ]
182 ; CHECK:       lor.rhs:
183 ; CHECK-NEXT:    br label [[LOR_END]]
184 ; CHECK:       lor.end:
185 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ]
186 ; CHECK-NEXT:    [[LOR_EXT:%.*]] = zext i1 [[TMP0]] to i32
187 ; CHECK-NEXT:    ret i32 [[LOR_EXT]]
189 entry:
190   switch i8 %c, label %lor.rhs [
191   i8 62, label %lor.end
192   i8 34, label %lor.end
193   i8 92, label %lor.end
194   ]
196 lor.rhs:                                          ; preds = %entry
197   %V = icmp eq i8 %c, 92
198   br label %lor.end
200 lor.end:                                          ; preds = %entry, %entry, %entry, %lor.rhs
201   %0 = phi i1 [ true, %entry ], [ %V, %lor.rhs ], [ true, %entry ], [ true, %entry ]
202   %lor.ext = zext i1 %0 to i32
203   ret i32 %lor.ext
207 define i1 @test6({ i32, i32 }* %I) {
208 ; CHECK-LABEL: @test6(
209 ; CHECK-NEXT:  entry:
210 ; CHECK-NEXT:    [[TMP_1_I:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[I:%.*]], i64 0, i32 1
211 ; CHECK-NEXT:    [[TMP_2_I:%.*]] = load i32, i32* [[TMP_1_I]]
212 ; CHECK-NEXT:    [[TMP_2_I_OFF:%.*]] = add i32 [[TMP_2_I]], -14
213 ; CHECK-NEXT:    [[SWITCH:%.*]] = icmp ult i32 [[TMP_2_I_OFF]], 6
214 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i1 true, i1 false
215 ; CHECK-NEXT:    ret i1 [[SPEC_SELECT]]
217 entry:
218   %tmp.1.i = getelementptr { i32, i32 }, { i32, i32 }* %I, i64 0, i32 1         ; <i32*> [#uses=1]
219   %tmp.2.i = load i32, i32* %tmp.1.i           ; <i32> [#uses=6]
220   %tmp.2 = icmp eq i32 %tmp.2.i, 14               ; <i1> [#uses=1]
221   br i1 %tmp.2, label %shortcirc_done.4, label %shortcirc_next.0
222 shortcirc_next.0:               ; preds = %entry
223   %tmp.6 = icmp eq i32 %tmp.2.i, 15               ; <i1> [#uses=1]
224   br i1 %tmp.6, label %shortcirc_done.4, label %shortcirc_next.1
225 shortcirc_next.1:               ; preds = %shortcirc_next.0
226   %tmp.11 = icmp eq i32 %tmp.2.i, 16              ; <i1> [#uses=1]
227   br i1 %tmp.11, label %shortcirc_done.4, label %shortcirc_next.2
228 shortcirc_next.2:               ; preds = %shortcirc_next.1
229   %tmp.16 = icmp eq i32 %tmp.2.i, 17              ; <i1> [#uses=1]
230   br i1 %tmp.16, label %shortcirc_done.4, label %shortcirc_next.3
231 shortcirc_next.3:               ; preds = %shortcirc_next.2
232   %tmp.21 = icmp eq i32 %tmp.2.i, 18              ; <i1> [#uses=1]
233   br i1 %tmp.21, label %shortcirc_done.4, label %shortcirc_next.4
234 shortcirc_next.4:               ; preds = %shortcirc_next.3
235   %tmp.26 = icmp eq i32 %tmp.2.i, 19              ; <i1> [#uses=1]
236   br label %UnifiedReturnBlock
237 shortcirc_done.4:               ; preds = %shortcirc_next.3, %shortcirc_next.2, %shortcirc_next.1, %shortcirc_next.0, %entry
238   br label %UnifiedReturnBlock
239 UnifiedReturnBlock:             ; preds = %shortcirc_done.4, %shortcirc_next.4
240   %UnifiedRetVal = phi i1 [ %tmp.26, %shortcirc_next.4 ], [ true, %shortcirc_done.4 ]             ; <i1> [#uses=1]
241   ret i1 %UnifiedRetVal
245 define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone {
246 ; CHECK-LABEL: @test7(
247 ; CHECK-NEXT:  entry:
248 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 32
249 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[SWITCH_EARLY_TEST:%.*]]
250 ; CHECK:       switch.early.test:
251 ; CHECK-NEXT:    switch i8 [[C:%.*]], label [[IF_END:%.*]] [
252 ; CHECK-NEXT:    i8 99, label [[IF_THEN]]
253 ; CHECK-NEXT:    i8 97, label [[IF_THEN]]
254 ; CHECK-NEXT:    ]
255 ; CHECK:       if.then:
256 ; CHECK-NEXT:    tail call void @foo1() #2
257 ; CHECK-NEXT:    ret void
258 ; CHECK:       if.end:
259 ; CHECK-NEXT:    ret void
261 entry:
262   %cmp = icmp ult i32 %x, 32
263   %cmp4 = icmp eq i8 %c, 97
264   %or.cond = or i1 %cmp, %cmp4
265   %cmp9 = icmp eq i8 %c, 99
266   %or.cond11 = or i1 %or.cond, %cmp9
267   br i1 %or.cond11, label %if.then, label %if.end
269 if.then:                                          ; preds = %entry
270   tail call void @foo1() nounwind noredzone
271   ret void
273 if.end:                                           ; preds = %entry
274   ret void
278 define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone {
279 ; CHECK-LABEL: @test8(
280 ; CHECK-NEXT:  entry:
281 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[N:%.*]], label [[IF_THEN:%.*]]
282 ; CHECK:       N:
283 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 32
284 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN]], label [[SWITCH_EARLY_TEST:%.*]]
285 ; CHECK:       switch.early.test:
286 ; CHECK-NEXT:    switch i8 [[C:%.*]], label [[IF_END:%.*]] [
287 ; CHECK-NEXT:    i8 99, label [[IF_THEN]]
288 ; CHECK-NEXT:    i8 97, label [[IF_THEN]]
289 ; CHECK-NEXT:    ]
290 ; CHECK:       if.then:
291 ; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 42, [[SWITCH_EARLY_TEST]] ], [ 42, [[N]] ], [ 42, [[SWITCH_EARLY_TEST]] ]
292 ; CHECK-NEXT:    tail call void @foo1() #2
293 ; CHECK-NEXT:    ret i32 [[A]]
294 ; CHECK:       if.end:
295 ; CHECK-NEXT:    ret i32 0
297 entry:
298   br i1 %C, label %N, label %if.then
300   %cmp = icmp ult i32 %x, 32
301   %cmp4 = icmp eq i8 %c, 97
302   %or.cond = or i1 %cmp, %cmp4
303   %cmp9 = icmp eq i8 %c, 99
304   %or.cond11 = or i1 %or.cond, %cmp9
305   br i1 %or.cond11, label %if.then, label %if.end
307 if.then:                                          ; preds = %entry
308   %A = phi i32 [0, %entry], [42, %N]
309   tail call void @foo1() nounwind noredzone
310   ret i32 %A
312 if.end:                                           ; preds = %entry
313   ret i32 0
317 ;; This is "Example 7" from http://blog.regehr.org/archives/320
318 define i32 @test9(i8 zeroext %c) nounwind ssp noredzone {
319 ; CHECK-LABEL: @test9(
320 ; CHECK-NEXT:  entry:
321 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[C:%.*]], 33
322 ; CHECK-NEXT:    br i1 [[CMP]], label [[LOR_END:%.*]], label [[SWITCH_EARLY_TEST:%.*]]
323 ; CHECK:       switch.early.test:
324 ; CHECK-NEXT:    switch i8 [[C]], label [[LOR_RHS:%.*]] [
325 ; CHECK-NEXT:    i8 92, label [[LOR_END]]
326 ; CHECK-NEXT:    i8 62, label [[LOR_END]]
327 ; CHECK-NEXT:    i8 60, label [[LOR_END]]
328 ; CHECK-NEXT:    i8 59, label [[LOR_END]]
329 ; CHECK-NEXT:    i8 58, label [[LOR_END]]
330 ; CHECK-NEXT:    i8 46, label [[LOR_END]]
331 ; CHECK-NEXT:    i8 44, label [[LOR_END]]
332 ; CHECK-NEXT:    i8 34, label [[LOR_END]]
333 ; CHECK-NEXT:    i8 39, label [[LOR_END]]
334 ; CHECK-NEXT:    ]
335 ; CHECK:       lor.rhs:
336 ; CHECK-NEXT:    br label [[LOR_END]]
337 ; CHECK:       lor.end:
338 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i1 [ true, [[SWITCH_EARLY_TEST]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY:%.*]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ]
339 ; CHECK-NEXT:    [[CONV46:%.*]] = zext i1 [[TMP0]] to i32
340 ; CHECK-NEXT:    ret i32 [[CONV46]]
342 entry:
343   %cmp = icmp ult i8 %c, 33
344   br i1 %cmp, label %lor.end, label %lor.lhs.false
346 lor.lhs.false:                                    ; preds = %entry
347   %cmp4 = icmp eq i8 %c, 46
348   br i1 %cmp4, label %lor.end, label %lor.lhs.false6
350 lor.lhs.false6:                                   ; preds = %lor.lhs.false
351   %cmp9 = icmp eq i8 %c, 44
352   br i1 %cmp9, label %lor.end, label %lor.lhs.false11
354 lor.lhs.false11:                                  ; preds = %lor.lhs.false6
355   %cmp14 = icmp eq i8 %c, 58
356   br i1 %cmp14, label %lor.end, label %lor.lhs.false16
358 lor.lhs.false16:                                  ; preds = %lor.lhs.false11
359   %cmp19 = icmp eq i8 %c, 59
360   br i1 %cmp19, label %lor.end, label %lor.lhs.false21
362 lor.lhs.false21:                                  ; preds = %lor.lhs.false16
363   %cmp24 = icmp eq i8 %c, 60
364   br i1 %cmp24, label %lor.end, label %lor.lhs.false26
366 lor.lhs.false26:                                  ; preds = %lor.lhs.false21
367   %cmp29 = icmp eq i8 %c, 62
368   br i1 %cmp29, label %lor.end, label %lor.lhs.false31
370 lor.lhs.false31:                                  ; preds = %lor.lhs.false26
371   %cmp34 = icmp eq i8 %c, 34
372   br i1 %cmp34, label %lor.end, label %lor.lhs.false36
374 lor.lhs.false36:                                  ; preds = %lor.lhs.false31
375   %cmp39 = icmp eq i8 %c, 92
376   br i1 %cmp39, label %lor.end, label %lor.rhs
378 lor.rhs:                                          ; preds = %lor.lhs.false36
379   %cmp43 = icmp eq i8 %c, 39
380   br label %lor.end
382 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
383   %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 ]
384   %conv46 = zext i1 %0 to i32
385   ret i32 %conv46
390 define i32 @test10(i32 %mode, i1 %Cond) {
391 ; CHECK-LABEL: @test10(
392 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[SWITCH_EARLY_TEST:%.*]], label [[F:%.*]]
393 ; CHECK:       switch.early.test:
394 ; CHECK-NEXT:    switch i32 [[MODE:%.*]], label [[T:%.*]] [
395 ; CHECK-NEXT:    i32 51, label [[F]]
396 ; CHECK-NEXT:    i32 0, label [[F]]
397 ; CHECK-NEXT:    ]
398 ; CHECK:       T:
399 ; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ 123, [[SWITCH_EARLY_TEST]] ], [ 324, [[F]] ]
400 ; CHECK-NEXT:    ret i32 [[MERGE]]
401 ; CHECK:       F:
402 ; CHECK-NEXT:    br label [[T]]
404   %A = icmp ne i32 %mode, 0
405   %B = icmp ne i32 %mode, 51
406   %C = and i1 %A, %B
407   %D = and i1 %C, %Cond
408   br i1 %D, label %T, label %F
410   ret i32 123
412   ret i32 324
416 ; PR8780
417 define i32 @test11(i32 %bar) nounwind {
418 ; CHECK-LABEL: @test11(
419 ; CHECK-NEXT:  entry:
420 ; CHECK-NEXT:    switch i32 [[BAR:%.*]], label [[IF_END:%.*]] [
421 ; CHECK-NEXT:    i32 55, label [[RETURN:%.*]]
422 ; CHECK-NEXT:    i32 53, label [[RETURN]]
423 ; CHECK-NEXT:    i32 35, label [[RETURN]]
424 ; CHECK-NEXT:    i32 24, label [[RETURN]]
425 ; CHECK-NEXT:    i32 23, label [[RETURN]]
426 ; CHECK-NEXT:    i32 12, label [[RETURN]]
427 ; CHECK-NEXT:    i32 4, label [[RETURN]]
428 ; CHECK-NEXT:    ]
429 ; CHECK:       if.end:
430 ; CHECK-NEXT:    br label [[RETURN]]
431 ; CHECK:       return:
432 ; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ 0, [[IF_END]] ], [ 1, [[ENTRY:%.*]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ]
433 ; CHECK-NEXT:    ret i32 [[RETVAL_0]]
435 entry:
436   %cmp = icmp eq i32 %bar, 4
437   %cmp2 = icmp eq i32 %bar, 35
438   %or.cond = or i1 %cmp, %cmp2
439   %cmp5 = icmp eq i32 %bar, 53
440   %or.cond1 = or i1 %or.cond, %cmp5
441   %cmp8 = icmp eq i32 %bar, 24
442   %or.cond2 = or i1 %or.cond1, %cmp8
443   %cmp11 = icmp eq i32 %bar, 23
444   %or.cond3 = or i1 %or.cond2, %cmp11
445   %cmp14 = icmp eq i32 %bar, 55
446   %or.cond4 = or i1 %or.cond3, %cmp14
447   %cmp17 = icmp eq i32 %bar, 12
448   %or.cond5 = or i1 %or.cond4, %cmp17
449   %cmp20 = icmp eq i32 %bar, 35
450   %or.cond6 = or i1 %or.cond5, %cmp20
451   br i1 %or.cond6, label %if.then, label %if.end
453 if.then:                                          ; preds = %entry
454   br label %return
456 if.end:                                           ; preds = %entry
457   br label %return
459 return:                                           ; preds = %if.end, %if.then
460   %retval.0 = phi i32 [ 1, %if.then ], [ 0, %if.end ]
461   ret i32 %retval.0
465 define void @test12() nounwind {
466 ; CHECK-LABEL: @test12(
467 ; CHECK-NEXT:  entry:
468 ; CHECK-NEXT:    [[A_OLD:%.*]] = icmp eq i32 undef, undef
469 ; CHECK-NEXT:    br i1 [[A_OLD]], label [[BB55_US_US:%.*]], label [[MALFORMED:%.*]]
470 ; CHECK:       bb55.us.us:
471 ; CHECK-NEXT:    [[B:%.*]] = icmp ugt i32 undef, undef
472 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 undef, undef
473 ; CHECK-NEXT:    [[OR_COND:%.*]] = or i1 [[B]], [[A]]
474 ; CHECK-NEXT:    br i1 [[OR_COND]], label [[BB55_US_US]], label [[MALFORMED]]
475 ; CHECK:       malformed:
476 ; CHECK-NEXT:    ret void
478 entry:
479   br label %bb49.us.us
481 bb49.us.us:
482   %A = icmp eq i32 undef, undef
483   br i1 %A, label %bb55.us.us, label %malformed
485 bb48.us.us:
486   %B = icmp ugt i32 undef, undef
487   br i1 %B, label %bb55.us.us, label %bb49.us.us
489 bb55.us.us:
490   br label %bb48.us.us
492 malformed:
493   ret void
497 ; test13 - handle switch formation with ult.
498 define void @test13(i32 %x) nounwind ssp noredzone {
499 ; CHECK-LABEL: @test13(
500 ; CHECK-NEXT:  entry:
501 ; CHECK-NEXT:    switch i32 [[X:%.*]], label [[IF_END:%.*]] [
502 ; CHECK-NEXT:    i32 6, label [[IF_THEN:%.*]]
503 ; CHECK-NEXT:    i32 4, label [[IF_THEN]]
504 ; CHECK-NEXT:    i32 3, label [[IF_THEN]]
505 ; CHECK-NEXT:    i32 1, label [[IF_THEN]]
506 ; CHECK-NEXT:    i32 0, label [[IF_THEN]]
507 ; CHECK-NEXT:    ]
508 ; CHECK:       if.then:
509 ; CHECK-NEXT:    call void @foo1() #3
510 ; CHECK-NEXT:    br label [[IF_END]]
511 ; CHECK:       if.end:
512 ; CHECK-NEXT:    ret void
514 entry:
515   %cmp = icmp ult i32 %x, 2
516   br i1 %cmp, label %if.then, label %lor.lhs.false3
518 lor.lhs.false3:                                   ; preds = %lor.lhs.false
519   %cmp5 = icmp eq i32 %x, 3
520   br i1 %cmp5, label %if.then, label %lor.lhs.false6
522 lor.lhs.false6:                                   ; preds = %lor.lhs.false3
523   %cmp8 = icmp eq i32 %x, 4
524   br i1 %cmp8, label %if.then, label %lor.lhs.false9
526 lor.lhs.false9:                                   ; preds = %lor.lhs.false6
527   %cmp11 = icmp eq i32 %x, 6
528   br i1 %cmp11, label %if.then, label %if.end
530 if.then:                                          ; preds = %lor.lhs.false9, %lor.lhs.false6, %lor.lhs.false3, %lor.lhs.false, %entry
531   call void @foo1() noredzone
532   br label %if.end
534 if.end:                                           ; preds = %if.then, %lor.lhs.false9
535   ret void
538 ; test14 - handle switch formation with ult.
539 define void @test14(i32 %x) nounwind ssp noredzone {
540 ; CHECK-LABEL: @test14(
541 ; CHECK-NEXT:  entry:
542 ; CHECK-NEXT:    switch i32 [[X:%.*]], label [[IF_END:%.*]] [
543 ; CHECK-NEXT:    i32 6, label [[IF_THEN:%.*]]
544 ; CHECK-NEXT:    i32 4, label [[IF_THEN]]
545 ; CHECK-NEXT:    i32 3, label [[IF_THEN]]
546 ; CHECK-NEXT:    i32 2, label [[IF_THEN]]
547 ; CHECK-NEXT:    i32 1, label [[IF_THEN]]
548 ; CHECK-NEXT:    i32 0, label [[IF_THEN]]
549 ; CHECK-NEXT:    ]
550 ; CHECK:       if.then:
551 ; CHECK-NEXT:    call void @foo1() #3
552 ; CHECK-NEXT:    br label [[IF_END]]
553 ; CHECK:       if.end:
554 ; CHECK-NEXT:    ret void
556 entry:
557   %cmp = icmp ugt i32 %x, 2
558   br i1 %cmp, label %lor.lhs.false3, label %if.then
560 lor.lhs.false3:                                   ; preds = %lor.lhs.false
561   %cmp5 = icmp ne i32 %x, 3
562   br i1 %cmp5, label %lor.lhs.false6, label %if.then
564 lor.lhs.false6:                                   ; preds = %lor.lhs.false3
565   %cmp8 = icmp ne i32 %x, 4
566   br i1 %cmp8, label %lor.lhs.false9, label %if.then
568 lor.lhs.false9:                                   ; preds = %lor.lhs.false6
569   %cmp11 = icmp ne i32 %x, 6
570   br i1 %cmp11, label %if.end, label %if.then
572 if.then:                                          ; preds = %lor.lhs.false9, %lor.lhs.false6, %lor.lhs.false3, %lor.lhs.false, %entry
573   call void @foo1() noredzone
574   br label %if.end
576 if.end:                                           ; preds = %if.then, %lor.lhs.false9
577   ret void
580 ; Don't crash on ginormous ranges.
581 define void @test15(i128 %x) nounwind {
582 ; CHECK-LABEL: @test15(
583 ; CHECK-NEXT:  if.end:
584 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i128 [[X:%.*]], 2
585 ; CHECK-NEXT:    ret void
587   %cmp = icmp ugt i128 %x, 2
588   br i1 %cmp, label %if.end, label %lor.false
590 lor.false:
591   %cmp2 = icmp ne i128 %x, 100000000000000000000
592   br i1 %cmp2, label %if.end, label %if.then
594 if.then:
595   call void @foo1() noredzone
596   br label %if.end
598 if.end:
599   ret void
603 ; PR8675
604 ; rdar://5134905
605 define zeroext i1 @test16(i32 %x) nounwind {
606 ; CHECK-LABEL: @test16(
607 ; CHECK-NEXT:  entry:
608 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], -1
609 ; CHECK-NEXT:    [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3
610 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i1 true, i1 false
611 ; CHECK-NEXT:    ret i1 [[SPEC_SELECT]]
613 entry:
614   %cmp.i = icmp eq i32 %x, 1
615   br i1 %cmp.i, label %lor.end, label %lor.lhs.false
617 lor.lhs.false:
618   %cmp.i2 = icmp eq i32 %x, 2
619   br i1 %cmp.i2, label %lor.end, label %lor.rhs
621 lor.rhs:
622   %cmp.i1 = icmp eq i32 %x, 3
623   br label %lor.end
625 lor.end:
626   %0 = phi i1 [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp.i1, %lor.rhs ]
627   ret i1 %0
630 ; Check that we don't turn an icmp into a switch where it's not useful.
631 define void @test17(i32 %x, i32 %y) {
632 ; CHECK-LABEL: @test17(
633 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3
634 ; CHECK-NEXT:    [[SWITCH:%.*]] = icmp ult i32 [[Y:%.*]], 2
635 ; CHECK-NEXT:    [[OR_COND775:%.*]] = or i1 [[CMP]], [[SWITCH]]
636 ; CHECK-NEXT:    br i1 [[OR_COND775]], label [[LOR_LHS_FALSE8:%.*]], label [[RETURN:%.*]]
637 ; CHECK:       lor.lhs.false8:
638 ; CHECK-NEXT:    tail call void @foo1()
639 ; CHECK-NEXT:    ret void
640 ; CHECK:       return:
641 ; CHECK-NEXT:    ret void
643   %cmp = icmp ult i32 %x, 3
644   %switch = icmp ult i32 %y, 2
645   %or.cond775 = or i1 %cmp, %switch
646   br i1 %or.cond775, label %lor.lhs.false8, label %return
648 lor.lhs.false8:
649   tail call void @foo1()
650   ret void
652 return:
653   ret void
657 define void @test18(i32 %arg) {
658 ; CHECK-LABEL: @test18(
659 ; CHECK-NEXT:  bb:
660 ; CHECK-NEXT:    [[ARG_OFF:%.*]] = add i32 [[ARG:%.*]], -8
661 ; CHECK-NEXT:    [[SWITCH:%.*]] = icmp ult i32 [[ARG_OFF]], 11
662 ; CHECK-NEXT:    br i1 [[SWITCH]], label [[BB19:%.*]], label [[BB20:%.*]]
663 ; CHECK:       bb19:
664 ; CHECK-NEXT:    tail call void @foo1()
665 ; CHECK-NEXT:    br label [[BB20]]
666 ; CHECK:       bb20:
667 ; CHECK-NEXT:    ret void
670   %tmp = and i32 %arg, -2
671   %tmp1 = icmp eq i32 %tmp, 8
672   %tmp2 = icmp eq i32 %arg, 10
673   %tmp3 = or i1 %tmp1, %tmp2
674   %tmp4 = icmp eq i32 %arg, 11
675   %tmp5 = or i1 %tmp3, %tmp4
676   %tmp6 = icmp eq i32 %arg, 12
677   %tmp7 = or i1 %tmp5, %tmp6
678   br i1 %tmp7, label %bb19, label %bb8
680 bb8:                                              ; preds = %bb
681   %tmp9 = add i32 %arg, -13
682   %tmp10 = icmp ult i32 %tmp9, 2
683   %tmp11 = icmp eq i32 %arg, 16
684   %tmp12 = or i1 %tmp10, %tmp11
685   %tmp13 = icmp eq i32 %arg, 17
686   %tmp14 = or i1 %tmp12, %tmp13
687   %tmp15 = icmp eq i32 %arg, 18
688   %tmp16 = or i1 %tmp14, %tmp15
689   %tmp17 = icmp eq i32 %arg, 15
690   %tmp18 = or i1 %tmp16, %tmp17
691   br i1 %tmp18, label %bb19, label %bb20
693 bb19:                                             ; preds = %bb8, %bb
694   tail call void @foo1()
695   br label %bb20
697 bb20:                                             ; preds = %bb19, %bb8
698   ret void
702 define void @PR26323(i1 %tobool23, i32 %tmp3) {
703 ; CHECK-LABEL: @PR26323(
704 ; CHECK-NEXT:  entry:
705 ; CHECK-NEXT:    [[TOBOOL5:%.*]] = icmp ne i32 [[TMP3:%.*]], 0
706 ; CHECK-NEXT:    [[NEG14:%.*]] = and i32 [[TMP3]], -2
707 ; CHECK-NEXT:    [[CMP17:%.*]] = icmp ne i32 [[NEG14]], -1
708 ; CHECK-NEXT:    [[OR_COND:%.*]] = and i1 [[TOBOOL5]], [[TOBOOL23:%.*]]
709 ; CHECK-NEXT:    [[OR_COND1:%.*]] = and i1 [[CMP17]], [[OR_COND]]
710 ; CHECK-NEXT:    br i1 [[OR_COND1]], label [[IF_END29:%.*]], label [[IF_THEN27:%.*]]
711 ; CHECK:       if.then27:
712 ; CHECK-NEXT:    call void @foo1()
713 ; CHECK-NEXT:    unreachable
714 ; CHECK:       if.end29:
715 ; CHECK-NEXT:    ret void
717 entry:
718   %tobool5 = icmp ne i32 %tmp3, 0
719   %neg14 = and i32 %tmp3, -2
720   %cmp17 = icmp ne i32 %neg14, -1
721   %or.cond = and i1 %tobool5, %tobool23
722   %or.cond1 = and i1 %cmp17, %or.cond
723   br i1 %or.cond1, label %if.end29, label %if.then27
725 if.then27:                                        ; preds = %entry
726   call void @foo1()
727   unreachable
729 if.end29:                                         ; preds = %entry
730   ret void
733 ; Form a switch when and'ing a negated power of two
734 define void @test19(i32 %arg) {
735 ; CHECK-LABEL: @test19(
736 ; CHECK-NEXT:    switch i32 [[ARG:%.*]], label [[ELSE:%.*]] [
737 ; CHECK-NEXT:    i32 32, label [[IF:%.*]]
738 ; CHECK-NEXT:    i32 13, label [[IF]]
739 ; CHECK-NEXT:    i32 12, label [[IF]]
740 ; CHECK-NEXT:    ]
741 ; CHECK:       if:
742 ; CHECK-NEXT:    call void @foo1()
743 ; CHECK-NEXT:    ret void
744 ; CHECK:       else:
745 ; CHECK-NEXT:    ret void
747   %and = and i32 %arg, -2
748   %cmp1 = icmp eq i32 %and, 12
749   %cmp2 = icmp eq i32 %arg, 32
750   %pred = or i1 %cmp1, %cmp2
751   br i1 %pred, label %if, label %else
754   call void @foo1()
755   ret void
757 else:
758   ret void
761 ; Since %cmp1 is always false, a switch is never formed
762 define void @test20(i32 %arg) {
763 ; CHECK-LABEL: @test20(
764 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[ARG:%.*]], -2
765 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[AND]], 13
766 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[ARG]], 32
767 ; CHECK-NEXT:    [[PRED:%.*]] = or i1 [[CMP1]], [[CMP2]]
768 ; CHECK-NEXT:    br i1 [[PRED]], label [[IF:%.*]], label [[ELSE:%.*]]
769 ; CHECK:       if:
770 ; CHECK-NEXT:    call void @foo1()
771 ; CHECK-NEXT:    ret void
772 ; CHECK:       else:
773 ; CHECK-NEXT:    ret void
775   %and = and i32 %arg, -2
776   %cmp1 = icmp eq i32 %and, 13
777   %cmp2 = icmp eq i32 %arg, 32
778   %pred = or i1 %cmp1, %cmp2
779   br i1 %pred, label %if, label %else
782   call void @foo1()
783   ret void
785 else:
786   ret void
789 ; Form a switch when or'ing a power of two
790 define void @test21(i32 %arg) {
791 ; CHECK-LABEL: @test21(
792 ; CHECK-NEXT:    switch i32 [[ARG:%.*]], label [[IF:%.*]] [
793 ; CHECK-NEXT:    i32 32, label [[ELSE:%.*]]
794 ; CHECK-NEXT:    i32 13, label [[ELSE]]
795 ; CHECK-NEXT:    i32 12, label [[ELSE]]
796 ; CHECK-NEXT:    ]
797 ; CHECK:       if:
798 ; CHECK-NEXT:    call void @foo1()
799 ; CHECK-NEXT:    ret void
800 ; CHECK:       else:
801 ; CHECK-NEXT:    ret void
803   %and = or i32 %arg, 1
804   %cmp1 = icmp ne i32 %and, 13
805   %cmp2 = icmp ne i32 %arg, 32
806   %pred = and i1 %cmp1, %cmp2
807   br i1 %pred, label %if, label %else
810   call void @foo1()
811   ret void
813 else:
814   ret void
817 ; Since %cmp1 is always false, a switch is never formed
818 define void @test22(i32 %arg) {
819 ; CHECK-LABEL: @test22(
820 ; CHECK-NEXT:    [[AND:%.*]] = or i32 [[ARG:%.*]], 1
821 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[AND]], 12
822 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i32 [[ARG]], 32
823 ; CHECK-NEXT:    [[PRED:%.*]] = and i1 [[CMP1]], [[CMP2]]
824 ; CHECK-NEXT:    br i1 [[PRED]], label [[IF:%.*]], label [[ELSE:%.*]]
825 ; CHECK:       if:
826 ; CHECK-NEXT:    call void @foo1()
827 ; CHECK-NEXT:    ret void
828 ; CHECK:       else:
829 ; CHECK-NEXT:    ret void
831   %and = or i32 %arg, 1
832   %cmp1 = icmp ne i32 %and, 12
833   %cmp2 = icmp ne i32 %arg, 32
834   %pred = and i1 %cmp1, %cmp2
835   br i1 %pred, label %if, label %else
838   call void @foo1()
839   ret void
841 else:
842   ret void