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