blob: 4e199bc85964bdb9f62a15207f0e8e337495c5da [file] [log] [blame]
Chris Lattnerd9bacc02010-12-13 03:18:54 +00001; RUN: opt < %s -simplifycfg -S | FileCheck %s
Chris Lattnerae509322004-02-24 05:34:44 +00002
Tanya Lattnerbaa370b2008-03-18 03:45:45 +00003declare void @foo1()
Chris Lattnerae509322004-02-24 05:34:44 +00004
Tanya Lattnerbaa370b2008-03-18 03:45:45 +00005declare void @foo2()
6
7define 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
12T: ; preds = %0
13 call void @foo1( )
14 ret void
15F: ; preds = %0
16 call void @foo2( )
17 ret void
Chris Lattnerd9bacc02010-12-13 03:18:54 +000018; CHECK: @test1
19; CHECK: switch i32 %V, label %F [
20; CHECK: i32 17, label %T
21; CHECK: i32 4, label %T
22; CHECK: ]
Chris Lattnerae509322004-02-24 05:34:44 +000023}
24
Tanya Lattnerbaa370b2008-03-18 03:45:45 +000025define 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
30T: ; preds = %0
31 call void @foo1( )
32 ret void
33F: ; preds = %0
34 call void @foo2( )
35 ret void
Chris Lattnerd9bacc02010-12-13 03:18:54 +000036; CHECK: @test2
37; CHECK: switch i32 %V, label %T [
38; CHECK: i32 17, label %F
39; CHECK: i32 4, label %F
40; CHECK: ]
Chris Lattnerae509322004-02-24 05:34:44 +000041}
42
Tanya Lattnerbaa370b2008-03-18 03:45:45 +000043define void @test3(i32 %V) {
44 %C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1]
45 br i1 %C1, label %T, label %N
46N: ; preds = %0
47 %C2 = icmp eq i32 %V, 17 ; <i1> [#uses=1]
48 br i1 %C2, label %T, label %F
49T: ; preds = %N, %0
50 call void @foo1( )
51 ret void
52F: ; preds = %N
53 call void @foo2( )
54 ret void
Chris Lattnerd9bacc02010-12-13 03:18:54 +000055
56; CHECK: @test3
57; CHECK: switch i32 %V, label %F [
58; CHECK: i32 4, label %T
59; CHECK: i32 17, label %T
60; CHECK: ]
Chris Lattner272f3522005-02-24 02:13:50 +000061}
62
63
Chris Lattnerd9bacc02010-12-13 03:18:54 +000064
65define i32 @test4(i8 zeroext %c) nounwind ssp noredzone {
66entry:
67 %cmp = icmp eq i8 %c, 62
68 br i1 %cmp, label %lor.end, label %lor.lhs.false
69
70lor.lhs.false: ; preds = %entry
71 %cmp4 = icmp eq i8 %c, 34
72 br i1 %cmp4, label %lor.end, label %lor.rhs
73
74lor.rhs: ; preds = %lor.lhs.false
75 %cmp8 = icmp eq i8 %c, 92
76 br label %lor.end
77
78lor.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
Chris Lattner62cc76e2010-12-13 03:43:57 +000091define i32 @test5(i8 zeroext %c) nounwind ssp noredzone {
92entry:
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
99lor.rhs: ; preds = %entry
100 %V = icmp eq i8 %c, 92
101 br label %lor.end
102
103lor.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}
Chris Lattnera7377212010-12-13 04:45:56 +0000114
115
116define i1 @test6({ i32, i32 }* %I) {
117entry:
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
122shortcirc_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
125shortcirc_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
128shortcirc_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
131shortcirc_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
134shortcirc_next.4: ; preds = %shortcirc_next.3
135 %tmp.26 = icmp eq i32 %tmp.2.i, 19 ; <i1> [#uses=1]
136 br label %UnifiedReturnBlock
137shortcirc_done.4: ; preds = %shortcirc_next.3, %shortcirc_next.2, %shortcirc_next.1, %shortcirc_next.0, %entry
138 br label %UnifiedReturnBlock
139UnifiedReturnBlock: ; 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
Evan Chengd983eba2011-01-29 04:46:23 +0000150; CHECK: i32 19, label %UnifiedReturnBlock
Chris Lattnera7377212010-12-13 04:45:56 +0000151; CHECK: ]
Chris Lattnera7377212010-12-13 04:45:56 +0000152}
153
Chris Lattnera442f242010-12-13 04:50:38 +0000154define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone {
155entry:
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
Chris Lattnera7377212010-12-13 04:45:56 +0000162
Chris Lattnera442f242010-12-13 04:50:38 +0000163if.then: ; preds = %entry
164 tail call void @foo1() nounwind noredzone
165 ret void
166
167if.end: ; preds = %entry
168 ret void
169
170; CHECK: @test7
Chris Lattnerfb836f82010-12-13 08:12:19 +0000171; 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: ]
Chris Lattnera442f242010-12-13 04:50:38 +0000178}
Chris Lattnercb570f82010-12-13 05:34:18 +0000179
180define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone {
181entry:
182 br i1 %C, label %N, label %if.then
183N:
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
191if.then: ; preds = %entry
192 %A = phi i32 [0, %entry], [42, %N]
193 tail call void @foo1() nounwind noredzone
194 ret i32 %A
195
196if.end: ; preds = %entry
197 ret i32 0
198
199; CHECK: @test8
Chris Lattnerfb836f82010-12-13 08:12:19 +0000200; 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 ]
Chris Lattnercb570f82010-12-13 05:34:18 +0000206}
Chris Lattnerfbeb5582010-12-13 07:00:06 +0000207
Chris Lattner79db3572010-12-13 07:41:29 +0000208;; This is "Example 7" from http://blog.regehr.org/archives/320
Chris Lattnerfbeb5582010-12-13 07:00:06 +0000209define i32 @test9(i8 zeroext %c) nounwind ssp noredzone {
210entry:
211 %cmp = icmp ult i8 %c, 33
212 br i1 %cmp, label %lor.end, label %lor.lhs.false
213
214lor.lhs.false: ; preds = %entry
215 %cmp4 = icmp eq i8 %c, 46
216 br i1 %cmp4, label %lor.end, label %lor.lhs.false6
217
218lor.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
222lor.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
226lor.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
230lor.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
234lor.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
238lor.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
242lor.lhs.false36: ; preds = %lor.lhs.false31
243 %cmp39 = icmp eq i8 %c, 92
244 br i1 %cmp39, label %lor.end, label %lor.rhs
245
246lor.rhs: ; preds = %lor.lhs.false36
247 %cmp43 = icmp eq i8 %c, 39
248 br label %lor.end
249
250lor.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
Chris Lattner7499b452010-12-14 08:46:09 +0000256; CHECK: %cmp = icmp ult i8 %c, 33
257; CHECK: br i1 %cmp, label %lor.end, label %switch.early.test
Chris Lattnerfbeb5582010-12-13 07:00:06 +0000258
Chris Lattner7499b452010-12-14 08:46:09 +0000259; 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: ]
Chris Lattnerfbeb5582010-12-13 07:00:06 +0000271}
272
Chris Lattnerfb836f82010-12-13 08:12:19 +0000273define 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
279T:
280 ret i32 123
281F:
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
Benjamin Kramer1e155ab2010-12-13 18:20:38 +0000293; PR8780
294define i32 @test11(i32 %bar) nounwind {
295entry:
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
Chris Lattnerfb836f82010-12-13 08:12:19 +0000312
Benjamin Kramer1e155ab2010-12-13 18:20:38 +0000313if.then: ; preds = %entry
314 br label %return
Chris Lattnerfbeb5582010-12-13 07:00:06 +0000315
Benjamin Kramer1e155ab2010-12-13 18:20:38 +0000316if.end: ; preds = %entry
317 br label %return
318
319return: ; 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}
Chris Lattnera6e5d562010-12-13 23:02:19 +0000334
335define void @test12() nounwind {
336entry:
337 br label %bb49.us.us
338
339bb49.us.us:
340 %A = icmp eq i32 undef, undef
341 br i1 %A, label %bb55.us.us, label %malformed
342
343bb48.us.us:
344 %B = icmp ugt i32 undef, undef
345 br i1 %B, label %bb55.us.us, label %bb49.us.us
346
347bb55.us.us:
348 br label %bb48.us.us
349
350malformed:
351 ret void
352; CHECK: @test12
353
Chris Lattnerd14b0f12010-12-17 06:20:15 +0000354}
355
356; test13 - handle switch formation with ult.
357define void @test13(i32 %x) nounwind ssp noredzone {
358entry:
359 %cmp = icmp ult i32 %x, 2
360 br i1 %cmp, label %if.then, label %lor.lhs.false3
361
362lor.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
366lor.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
370lor.lhs.false9: ; preds = %lor.lhs.false6
371 %cmp11 = icmp eq i32 %x, 6
372 br i1 %cmp11, label %if.then, label %if.end
373
374if.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
378if.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.
391define void @test14(i32 %x) nounwind ssp noredzone {
392entry:
393 %cmp = icmp ugt i32 %x, 2
394 br i1 %cmp, label %lor.lhs.false3, label %if.then
395
396lor.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
400lor.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
404lor.lhs.false9: ; preds = %lor.lhs.false6
405 %cmp11 = icmp ne i32 %x, 6
406 br i1 %cmp11, label %if.end, label %if.then
407
408if.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
412if.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
Benjamin Kramere5f49c42010-12-17 10:48:14 +0000424; Don't crash on ginormous ranges.
425define void @test15(i128 %x) nounwind {
426 %cmp = icmp ugt i128 %x, 2
427 br i1 %cmp, label %if.end, label %lor.false
428
429lor.false:
430 %cmp2 = icmp ne i128 %x, 100000000000000000000
431 br i1 %cmp2, label %if.end, label %if.then
432
433if.then:
434 call void @foo1() noredzone
435 br label %if.end
436
437if.end:
438 ret void
439
440; CHECK: @test15
441; CHECK-NOT: switch
442; CHECK: ret void
443}
Evan Chengd983eba2011-01-29 04:46:23 +0000444
445; PR8675
446; rdar://5134905
447define zeroext i1 @test16(i32 %x) nounwind {
448entry:
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
458lor.lhs.false:
459 %cmp.i2 = icmp eq i32 %x, 2
460 br i1 %cmp.i2, label %lor.end, label %lor.rhs
461
462lor.rhs:
463 %cmp.i1 = icmp eq i32 %x, 3
464 br label %lor.end
465
466lor.end:
467 %0 = phi i1 [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp.i1, %lor.rhs ]
468 ret i1 %0
469}