1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %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(i32* %V) {
37; CHECK-LABEL: @test1_ptr(
38; CHECK-NEXT:    [[MAGICPTR:%.*]] = ptrtoint i32* [[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 i32* %V, inttoptr (i32 4 to i32*)
53  %C2 = icmp eq i32* %V, inttoptr (i32 17 to i32*)
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(i32 addrspace(1)* %V) {
65; CHECK-LABEL: @test1_ptr_as1(
66; CHECK-NEXT:    [[MAGICPTR:%.*]] = ptrtoint i32 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 i32 addrspace(1)* %V, inttoptr (i32 4 to i32 addrspace(1)*)
81  %C2 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 17 to i32 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({ i32, i32 }* %I) {
218; CHECK-LABEL: @test6(
219; CHECK-NEXT:  entry:
220; CHECK-NEXT:    [[TMP_1_I:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[I:%.*]], i64 0, i32 1
221; CHECK-NEXT:    [[TMP_2_I:%.*]] = load i32, i32* [[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 }, { i32, i32 }* %I, i64 0, i32 1         ; <i32*> [#uses=1]
229  %tmp.2.i = load i32, i32* %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:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[SWITCH_EARLY_TEST:%.*]]
260; CHECK:       switch.early.test:
261; CHECK-NEXT:    switch i8 [[C:%.*]], label [[COMMON_RET:%.*]] [
262; CHECK-NEXT:    i8 99, label [[IF_THEN]]
263; CHECK-NEXT:    i8 97, label [[IF_THEN]]
264; CHECK-NEXT:    ]
265; CHECK:       common.ret:
266; CHECK-NEXT:    ret void
267; CHECK:       if.then:
268; CHECK-NEXT:    tail call void @foo1() #[[ATTR2:[0-9]+]]
269; CHECK-NEXT:    br label [[COMMON_RET]]
270;
271entry:
272  %cmp = icmp ult i32 %x, 32
273  %cmp4 = icmp eq i8 %c, 97
274  %or.cond = or i1 %cmp, %cmp4
275  %cmp9 = icmp eq i8 %c, 99
276  %or.cond11 = or i1 %or.cond, %cmp9
277  br i1 %or.cond11, label %if.then, label %if.end
278
279if.then:                                          ; preds = %entry
280  tail call void @foo1() nounwind noredzone
281  ret void
282
283if.end:                                           ; preds = %entry
284  ret void
285
286}
287
288define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone {
289; CHECK-LABEL: @test8(
290; CHECK-NEXT:  entry:
291; CHECK-NEXT:    br i1 [[C:%.*]], label [[N:%.*]], label [[IF_THEN:%.*]]
292; CHECK:       N:
293; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 32
294; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN]], label [[SWITCH_EARLY_TEST:%.*]]
295; CHECK:       switch.early.test:
296; CHECK-NEXT:    switch i8 [[C:%.*]], label [[COMMON_RET:%.*]] [
297; CHECK-NEXT:    i8 99, label [[IF_THEN]]
298; CHECK-NEXT:    i8 97, label [[IF_THEN]]
299; CHECK-NEXT:    ]
300; CHECK:       common.ret:
301; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i32 [ [[A:%.*]], [[IF_THEN]] ], [ 0, [[SWITCH_EARLY_TEST]] ]
302; CHECK-NEXT:    ret i32 [[COMMON_RET_OP]]
303; CHECK:       if.then:
304; CHECK-NEXT:    [[A]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 42, [[SWITCH_EARLY_TEST]] ], [ 42, [[N]] ], [ 42, [[SWITCH_EARLY_TEST]] ]
305; CHECK-NEXT:    tail call void @foo1() #[[ATTR2]]
306; CHECK-NEXT:    br label [[COMMON_RET]]
307;
308entry:
309  br i1 %C, label %N, label %if.then
310N:
311  %cmp = icmp ult i32 %x, 32
312  %cmp4 = icmp eq i8 %c, 97
313  %or.cond = or i1 %cmp, %cmp4
314  %cmp9 = icmp eq i8 %c, 99
315  %or.cond11 = or i1 %or.cond, %cmp9
316  br i1 %or.cond11, label %if.then, label %if.end
317
318if.then:                                          ; preds = %entry
319  %A = phi i32 [0, %entry], [42, %N]
320  tail call void @foo1() nounwind noredzone
321  ret i32 %A
322
323if.end:                                           ; preds = %entry
324  ret i32 0
325
326}
327
328;; This is "Example 7" from http://blog.regehr.org/archives/320
329define i32 @test9(i8 zeroext %c) nounwind ssp noredzone {
330; CHECK-LABEL: @test9(
331; CHECK-NEXT:  entry:
332; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i8 [[C:%.*]], 33
333; CHECK-NEXT:    br i1 [[CMP]], label [[LOR_END:%.*]], label [[SWITCH_EARLY_TEST:%.*]]
334; CHECK:       switch.early.test:
335; CHECK-NEXT:    switch i8 [[C]], label [[LOR_RHS:%.*]] [
336; CHECK-NEXT:    i8 92, label [[LOR_END]]
337; CHECK-NEXT:    i8 62, label [[LOR_END]]
338; CHECK-NEXT:    i8 60, label [[LOR_END]]
339; CHECK-NEXT:    i8 59, label [[LOR_END]]
340; CHECK-NEXT:    i8 58, label [[LOR_END]]
341; CHECK-NEXT:    i8 46, label [[LOR_END]]
342; CHECK-NEXT:    i8 44, label [[LOR_END]]
343; CHECK-NEXT:    i8 34, label [[LOR_END]]
344; CHECK-NEXT:    i8 39, label [[LOR_END]]
345; CHECK-NEXT:    ]
346; CHECK:       lor.rhs:
347; CHECK-NEXT:    br label [[LOR_END]]
348; CHECK:       lor.end:
349; 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]] ]
350; CHECK-NEXT:    [[CONV46:%.*]] = zext i1 [[TMP0]] to i32
351; CHECK-NEXT:    ret i32 [[CONV46]]
352;
353entry:
354  %cmp = icmp ult i8 %c, 33
355  br i1 %cmp, label %lor.end, label %lor.lhs.false
356
357lor.lhs.false:                                    ; preds = %entry
358  %cmp4 = icmp eq i8 %c, 46
359  br i1 %cmp4, label %lor.end, label %lor.lhs.false6
360
361lor.lhs.false6:                                   ; preds = %lor.lhs.false
362  %cmp9 = icmp eq i8 %c, 44
363  br i1 %cmp9, label %lor.end, label %lor.lhs.false11
364
365lor.lhs.false11:                                  ; preds = %lor.lhs.false6
366  %cmp14 = icmp eq i8 %c, 58
367  br i1 %cmp14, label %lor.end, label %lor.lhs.false16
368
369lor.lhs.false16:                                  ; preds = %lor.lhs.false11
370  %cmp19 = icmp eq i8 %c, 59
371  br i1 %cmp19, label %lor.end, label %lor.lhs.false21
372
373lor.lhs.false21:                                  ; preds = %lor.lhs.false16
374  %cmp24 = icmp eq i8 %c, 60
375  br i1 %cmp24, label %lor.end, label %lor.lhs.false26
376
377lor.lhs.false26:                                  ; preds = %lor.lhs.false21
378  %cmp29 = icmp eq i8 %c, 62
379  br i1 %cmp29, label %lor.end, label %lor.lhs.false31
380
381lor.lhs.false31:                                  ; preds = %lor.lhs.false26
382  %cmp34 = icmp eq i8 %c, 34
383  br i1 %cmp34, label %lor.end, label %lor.lhs.false36
384
385lor.lhs.false36:                                  ; preds = %lor.lhs.false31
386  %cmp39 = icmp eq i8 %c, 92
387  br i1 %cmp39, label %lor.end, label %lor.rhs
388
389lor.rhs:                                          ; preds = %lor.lhs.false36
390  %cmp43 = icmp eq i8 %c, 39
391  br label %lor.end
392
393lor.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
394  %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 ]
395  %conv46 = zext i1 %0 to i32
396  ret i32 %conv46
397
398
399}
400
401define i32 @test10(i32 %mode, i1 %Cond) {
402; CHECK-LABEL: @test10(
403; CHECK-NEXT:    br i1 [[COND:%.*]], label [[SWITCH_EARLY_TEST:%.*]], label [[F:%.*]]
404; CHECK:       switch.early.test:
405; CHECK-NEXT:    switch i32 [[MODE:%.*]], label [[T:%.*]] [
406; CHECK-NEXT:    i32 51, label [[F]]
407; CHECK-NEXT:    i32 0, label [[F]]
408; CHECK-NEXT:    ]
409; CHECK:       common.ret:
410; CHECK-NEXT:    [[COMMON_RET_OP:%.*]] = phi i32 [ 123, [[T]] ], [ 324, [[F]] ]
411; CHECK-NEXT:    ret i32 [[COMMON_RET_OP]]
412; CHECK:       T:
413; CHECK-NEXT:    call void @foo1()
414; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
415; CHECK:       F:
416; CHECK-NEXT:    call void @foo2()
417; CHECK-NEXT:    br label [[COMMON_RET]]
418;
419  %A = icmp ne i32 %mode, 0
420  %B = icmp ne i32 %mode, 51
421  %C = and i1 %A, %B
422  %D = and i1 %C, %Cond
423  br i1 %D, label %T, label %F
424T:
425  call void @foo1()
426  ret i32 123
427F:
428  call void @foo2()
429  ret i32 324
430
431}
432
433; PR8780
434define i32 @test11(i32 %bar) nounwind {
435; CHECK-LABEL: @test11(
436; CHECK-NEXT:  entry:
437; CHECK-NEXT:    switch i32 [[BAR:%.*]], label [[IF_END:%.*]] [
438; CHECK-NEXT:    i32 55, label [[RETURN:%.*]]
439; CHECK-NEXT:    i32 53, label [[RETURN]]
440; CHECK-NEXT:    i32 35, label [[RETURN]]
441; CHECK-NEXT:    i32 24, label [[RETURN]]
442; CHECK-NEXT:    i32 23, label [[RETURN]]
443; CHECK-NEXT:    i32 12, label [[RETURN]]
444; CHECK-NEXT:    i32 4, label [[RETURN]]
445; CHECK-NEXT:    ]
446; CHECK:       if.end:
447; CHECK-NEXT:    br label [[RETURN]]
448; CHECK:       return:
449; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ 0, [[IF_END]] ], [ 1, [[ENTRY:%.*]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ]
450; CHECK-NEXT:    ret i32 [[RETVAL_0]]
451;
452entry:
453  %cmp = icmp eq i32 %bar, 4
454  %cmp2 = icmp eq i32 %bar, 35
455  %or.cond = or i1 %cmp, %cmp2
456  %cmp5 = icmp eq i32 %bar, 53
457  %or.cond1 = or i1 %or.cond, %cmp5
458  %cmp8 = icmp eq i32 %bar, 24
459  %or.cond2 = or i1 %or.cond1, %cmp8
460  %cmp11 = icmp eq i32 %bar, 23
461  %or.cond3 = or i1 %or.cond2, %cmp11
462  %cmp14 = icmp eq i32 %bar, 55
463  %or.cond4 = or i1 %or.cond3, %cmp14
464  %cmp17 = icmp eq i32 %bar, 12
465  %or.cond5 = or i1 %or.cond4, %cmp17
466  %cmp20 = icmp eq i32 %bar, 35
467  %or.cond6 = or i1 %or.cond5, %cmp20
468  br i1 %or.cond6, label %if.then, label %if.end
469
470if.then:                                          ; preds = %entry
471  br label %return
472
473if.end:                                           ; preds = %entry
474  br label %return
475
476return:                                           ; preds = %if.end, %if.then
477  %retval.0 = phi i32 [ 1, %if.then ], [ 0, %if.end ]
478  ret i32 %retval.0
479
480}
481
482define void @test12() nounwind {
483; CHECK-LABEL: @test12(
484; CHECK-NEXT:  entry:
485; CHECK-NEXT:    [[A_OLD:%.*]] = icmp eq i32 undef, undef
486; CHECK-NEXT:    br i1 [[A_OLD]], label [[BB55_US_US:%.*]], label [[MALFORMED:%.*]]
487; CHECK:       bb55.us.us:
488; CHECK-NEXT:    [[B:%.*]] = icmp ugt i32 undef, undef
489; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 undef, undef
490; CHECK-NEXT:    [[OR_COND:%.*]] = or i1 [[B]], [[A]]
491; CHECK-NEXT:    br i1 [[OR_COND]], label [[BB55_US_US]], label [[MALFORMED]]
492; CHECK:       malformed:
493; CHECK-NEXT:    ret void
494;
495entry:
496  br label %bb49.us.us
497
498bb49.us.us:
499  %A = icmp eq i32 undef, undef
500  br i1 %A, label %bb55.us.us, label %malformed
501
502bb48.us.us:
503  %B = icmp ugt i32 undef, undef
504  br i1 %B, label %bb55.us.us, label %bb49.us.us
505
506bb55.us.us:
507  br label %bb48.us.us
508
509malformed:
510  ret void
511
512}
513
514; test13 - handle switch formation with ult.
515define void @test13(i32 %x) nounwind ssp noredzone {
516; CHECK-LABEL: @test13(
517; CHECK-NEXT:  entry:
518; CHECK-NEXT:    switch i32 [[X:%.*]], label [[IF_END:%.*]] [
519; CHECK-NEXT:    i32 6, label [[IF_THEN:%.*]]
520; CHECK-NEXT:    i32 4, label [[IF_THEN]]
521; CHECK-NEXT:    i32 3, label [[IF_THEN]]
522; CHECK-NEXT:    i32 1, label [[IF_THEN]]
523; CHECK-NEXT:    i32 0, label [[IF_THEN]]
524; CHECK-NEXT:    ]
525; CHECK:       if.then:
526; CHECK-NEXT:    call void @foo1() #[[ATTR3:[0-9]+]]
527; CHECK-NEXT:    br label [[IF_END]]
528; CHECK:       if.end:
529; CHECK-NEXT:    ret void
530;
531entry:
532  %cmp = icmp ult i32 %x, 2
533  br i1 %cmp, label %if.then, label %lor.lhs.false3
534
535lor.lhs.false3:                                   ; preds = %lor.lhs.false
536  %cmp5 = icmp eq i32 %x, 3
537  br i1 %cmp5, label %if.then, label %lor.lhs.false6
538
539lor.lhs.false6:                                   ; preds = %lor.lhs.false3
540  %cmp8 = icmp eq i32 %x, 4
541  br i1 %cmp8, label %if.then, label %lor.lhs.false9
542
543lor.lhs.false9:                                   ; preds = %lor.lhs.false6
544  %cmp11 = icmp eq i32 %x, 6
545  br i1 %cmp11, label %if.then, label %if.end
546
547if.then:                                          ; preds = %lor.lhs.false9, %lor.lhs.false6, %lor.lhs.false3, %lor.lhs.false, %entry
548  call void @foo1() noredzone
549  br label %if.end
550
551if.end:                                           ; preds = %if.then, %lor.lhs.false9
552  ret void
553}
554
555; test14 - handle switch formation with ult.
556define void @test14(i32 %x) nounwind ssp noredzone {
557; CHECK-LABEL: @test14(
558; CHECK-NEXT:  entry:
559; CHECK-NEXT:    switch i32 [[X:%.*]], label [[IF_END:%.*]] [
560; CHECK-NEXT:    i32 6, label [[IF_THEN:%.*]]
561; CHECK-NEXT:    i32 4, label [[IF_THEN]]
562; CHECK-NEXT:    i32 3, label [[IF_THEN]]
563; CHECK-NEXT:    i32 2, label [[IF_THEN]]
564; CHECK-NEXT:    i32 1, label [[IF_THEN]]
565; CHECK-NEXT:    i32 0, label [[IF_THEN]]
566; CHECK-NEXT:    ]
567; CHECK:       if.then:
568; CHECK-NEXT:    call void @foo1() #[[ATTR3]]
569; CHECK-NEXT:    br label [[IF_END]]
570; CHECK:       if.end:
571; CHECK-NEXT:    ret void
572;
573entry:
574  %cmp = icmp ugt i32 %x, 2
575  br i1 %cmp, label %lor.lhs.false3, label %if.then
576
577lor.lhs.false3:                                   ; preds = %lor.lhs.false
578  %cmp5 = icmp ne i32 %x, 3
579  br i1 %cmp5, label %lor.lhs.false6, label %if.then
580
581lor.lhs.false6:                                   ; preds = %lor.lhs.false3
582  %cmp8 = icmp ne i32 %x, 4
583  br i1 %cmp8, label %lor.lhs.false9, label %if.then
584
585lor.lhs.false9:                                   ; preds = %lor.lhs.false6
586  %cmp11 = icmp ne i32 %x, 6
587  br i1 %cmp11, label %if.end, label %if.then
588
589if.then:                                          ; preds = %lor.lhs.false9, %lor.lhs.false6, %lor.lhs.false3, %lor.lhs.false, %entry
590  call void @foo1() noredzone
591  br label %if.end
592
593if.end:                                           ; preds = %if.then, %lor.lhs.false9
594  ret void
595}
596
597; Don't crash on ginormous ranges.
598define void @test15(i128 %x) nounwind {
599; CHECK-LABEL: @test15(
600; CHECK-NEXT:  if.end:
601; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i128 [[X:%.*]], 2
602; CHECK-NEXT:    ret void
603;
604  %cmp = icmp ugt i128 %x, 2
605  br i1 %cmp, label %if.end, label %lor.false
606
607lor.false:
608  %cmp2 = icmp ne i128 %x, 100000000000000000000
609  br i1 %cmp2, label %if.end, label %if.then
610
611if.then:
612  call void @foo1() noredzone
613  br label %if.end
614
615if.end:
616  ret void
617
618}
619
620; PR8675
621; rdar://5134905
622define zeroext i1 @test16(i32 %x) nounwind {
623; CHECK-LABEL: @test16(
624; CHECK-NEXT:  entry:
625; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], -1
626; CHECK-NEXT:    [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3
627; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i1 true, i1 false
628; CHECK-NEXT:    ret i1 [[SPEC_SELECT]]
629;
630entry:
631  %cmp.i = icmp eq i32 %x, 1
632  br i1 %cmp.i, label %lor.end, label %lor.lhs.false
633
634lor.lhs.false:
635  %cmp.i2 = icmp eq i32 %x, 2
636  br i1 %cmp.i2, label %lor.end, label %lor.rhs
637
638lor.rhs:
639  %cmp.i1 = icmp eq i32 %x, 3
640  br label %lor.end
641
642lor.end:
643  %0 = phi i1 [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp.i1, %lor.rhs ]
644  ret i1 %0
645}
646
647; Check that we don't turn an icmp into a switch where it's not useful.
648define void @test17(i32 %x, i32 %y) {
649; CHECK-LABEL: @test17(
650; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3
651; CHECK-NEXT:    [[SWITCH:%.*]] = icmp ult i32 [[Y:%.*]], 2
652; CHECK-NEXT:    [[OR_COND775:%.*]] = or i1 [[CMP]], [[SWITCH]]
653; CHECK-NEXT:    br i1 [[OR_COND775]], label [[LOR_LHS_FALSE8:%.*]], label [[COMMON_RET:%.*]]
654; CHECK:       common.ret:
655; CHECK-NEXT:    ret void
656; CHECK:       lor.lhs.false8:
657; CHECK-NEXT:    tail call void @foo1()
658; CHECK-NEXT:    br label [[COMMON_RET]]
659;
660  %cmp = icmp ult i32 %x, 3
661  %switch = icmp ult i32 %y, 2
662  %or.cond775 = or i1 %cmp, %switch
663  br i1 %or.cond775, label %lor.lhs.false8, label %return
664
665lor.lhs.false8:
666  tail call void @foo1()
667  ret void
668
669return:
670  ret void
671
672}
673
674define void @test18(i32 %arg) {
675; CHECK-LABEL: @test18(
676; CHECK-NEXT:  bb:
677; CHECK-NEXT:    [[ARG_OFF:%.*]] = add i32 [[ARG:%.*]], -8
678; CHECK-NEXT:    [[SWITCH:%.*]] = icmp ult i32 [[ARG_OFF]], 11
679; CHECK-NEXT:    br i1 [[SWITCH]], label [[BB19:%.*]], label [[BB20:%.*]]
680; CHECK:       bb19:
681; CHECK-NEXT:    tail call void @foo1()
682; CHECK-NEXT:    br label [[BB20]]
683; CHECK:       bb20:
684; CHECK-NEXT:    ret void
685;
686bb:
687  %tmp = and i32 %arg, -2
688  %tmp1 = icmp eq i32 %tmp, 8
689  %tmp2 = icmp eq i32 %arg, 10
690  %tmp3 = or i1 %tmp1, %tmp2
691  %tmp4 = icmp eq i32 %arg, 11
692  %tmp5 = or i1 %tmp3, %tmp4
693  %tmp6 = icmp eq i32 %arg, 12
694  %tmp7 = or i1 %tmp5, %tmp6
695  br i1 %tmp7, label %bb19, label %bb8
696
697bb8:                                              ; preds = %bb
698  %tmp9 = add i32 %arg, -13
699  %tmp10 = icmp ult i32 %tmp9, 2
700  %tmp11 = icmp eq i32 %arg, 16
701  %tmp12 = or i1 %tmp10, %tmp11
702  %tmp13 = icmp eq i32 %arg, 17
703  %tmp14 = or i1 %tmp12, %tmp13
704  %tmp15 = icmp eq i32 %arg, 18
705  %tmp16 = or i1 %tmp14, %tmp15
706  %tmp17 = icmp eq i32 %arg, 15
707  %tmp18 = or i1 %tmp16, %tmp17
708  br i1 %tmp18, label %bb19, label %bb20
709
710bb19:                                             ; preds = %bb8, %bb
711  tail call void @foo1()
712  br label %bb20
713
714bb20:                                             ; preds = %bb19, %bb8
715  ret void
716
717}
718
719define void @PR26323(i1 %tobool23, i32 %tmp3) {
720; CHECK-LABEL: @PR26323(
721; CHECK-NEXT:  entry:
722; CHECK-NEXT:    [[TOBOOL5:%.*]] = icmp ne i32 [[TMP3:%.*]], 0
723; CHECK-NEXT:    [[NEG14:%.*]] = and i32 [[TMP3]], -2
724; CHECK-NEXT:    [[CMP17:%.*]] = icmp ne i32 [[NEG14]], -1
725; CHECK-NEXT:    [[OR_COND:%.*]] = and i1 [[TOBOOL5]], [[TOBOOL23:%.*]]
726; CHECK-NEXT:    [[OR_COND1:%.*]] = and i1 [[CMP17]], [[OR_COND]]
727; CHECK-NEXT:    br i1 [[OR_COND1]], label [[IF_END29:%.*]], label [[IF_THEN27:%.*]]
728; CHECK:       if.then27:
729; CHECK-NEXT:    call void @foo1()
730; CHECK-NEXT:    unreachable
731; CHECK:       if.end29:
732; CHECK-NEXT:    ret void
733;
734entry:
735  %tobool5 = icmp ne i32 %tmp3, 0
736  %neg14 = and i32 %tmp3, -2
737  %cmp17 = icmp ne i32 %neg14, -1
738  %or.cond = and i1 %tobool5, %tobool23
739  %or.cond1 = and i1 %cmp17, %or.cond
740  br i1 %or.cond1, label %if.end29, label %if.then27
741
742if.then27:                                        ; preds = %entry
743  call void @foo1()
744  unreachable
745
746if.end29:                                         ; preds = %entry
747  ret void
748}
749
750define void @test19(i32 %arg) {
751; CHECK-LABEL: @test19(
752; CHECK-NEXT:    switch i32 [[ARG:%.*]], label [[COMMON_RET:%.*]] [
753; CHECK-NEXT:    i32 32, label [[IF:%.*]]
754; CHECK-NEXT:    i32 13, label [[IF]]
755; CHECK-NEXT:    i32 12, label [[IF]]
756; CHECK-NEXT:    ]
757; CHECK:       common.ret:
758; CHECK-NEXT:    ret void
759; CHECK:       if:
760; CHECK-NEXT:    call void @foo1()
761; CHECK-NEXT:    br label [[COMMON_RET]]
762;
763  %and = and i32 %arg, -2
764  %cmp1 = icmp eq i32 %and, 12
765  %cmp2 = icmp eq i32 %arg, 32
766  %pred = or i1 %cmp1, %cmp2
767  br i1 %pred, label %if, label %else
768
769if:
770  call void @foo1()
771  ret void
772
773else:
774  ret void
775}
776
777; Since %cmp1 is always false, a switch is never formed
778define void @test20(i32 %arg) {
779; CHECK-LABEL: @test20(
780; CHECK-NEXT:    [[AND:%.*]] = and i32 [[ARG:%.*]], -2
781; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[AND]], 13
782; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[ARG]], 32
783; CHECK-NEXT:    [[PRED:%.*]] = or i1 [[CMP1]], [[CMP2]]
784; CHECK-NEXT:    br i1 [[PRED]], label [[IF:%.*]], label [[COMMON_RET:%.*]]
785; CHECK:       common.ret:
786; CHECK-NEXT:    ret void
787; CHECK:       if:
788; CHECK-NEXT:    call void @foo1()
789; CHECK-NEXT:    br label [[COMMON_RET]]
790;
791  %and = and i32 %arg, -2
792  %cmp1 = icmp eq i32 %and, 13
793  %cmp2 = icmp eq i32 %arg, 32
794  %pred = or i1 %cmp1, %cmp2
795  br i1 %pred, label %if, label %else
796
797if:
798  call void @foo1()
799  ret void
800
801else:
802  ret void
803}
804
805; Form a switch when or'ing a power of two
806define void @test21(i32 %arg) {
807; CHECK-LABEL: @test21(
808; CHECK-NEXT:    switch i32 [[ARG:%.*]], label [[IF:%.*]] [
809; CHECK-NEXT:    i32 32, label [[COMMON_RET:%.*]]
810; CHECK-NEXT:    i32 13, label [[COMMON_RET]]
811; CHECK-NEXT:    i32 12, label [[COMMON_RET]]
812; CHECK-NEXT:    ]
813; CHECK:       common.ret:
814; CHECK-NEXT:    ret void
815; CHECK:       if:
816; CHECK-NEXT:    call void @foo1()
817; CHECK-NEXT:    br label [[COMMON_RET]]
818;
819  %and = or i32 %arg, 1
820  %cmp1 = icmp ne i32 %and, 13
821  %cmp2 = icmp ne i32 %arg, 32
822  %pred = and i1 %cmp1, %cmp2
823  br i1 %pred, label %if, label %else
824
825if:
826  call void @foo1()
827  ret void
828
829else:
830  ret void
831}
832
833; Since %cmp1 is always false, a switch is never formed
834define void @test22(i32 %arg) {
835; CHECK-LABEL: @test22(
836; CHECK-NEXT:    [[AND:%.*]] = or i32 [[ARG:%.*]], 1
837; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[AND]], 12
838; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i32 [[ARG]], 32
839; CHECK-NEXT:    [[PRED:%.*]] = and i1 [[CMP1]], [[CMP2]]
840; CHECK-NEXT:    br i1 [[PRED]], label [[IF:%.*]], label [[COMMON_RET:%.*]]
841; CHECK:       common.ret:
842; CHECK-NEXT:    ret void
843; CHECK:       if:
844; CHECK-NEXT:    call void @foo1()
845; CHECK-NEXT:    br label [[COMMON_RET]]
846;
847  %and = or i32 %arg, 1
848  %cmp1 = icmp ne i32 %and, 12
849  %cmp2 = icmp ne i32 %arg, 32
850  %pred = and i1 %cmp1, %cmp2
851  br i1 %pred, label %if, label %else
852
853if:
854  call void @foo1()
855  ret void
856
857else:
858  ret void
859}
860