blob: 0174abf2b064005daf46b8e4ed8dcd39eec2425c [file] [log] [blame]
Sanjay Patel28249272017-04-09 16:16:32 +00001; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
James Molloy4de84dd2015-11-04 15:28:04 +00002; RUN: opt -simplifycfg -instcombine < %s -simplifycfg-merge-cond-stores=true -simplifycfg-merge-cond-stores-aggressively=false -phi-node-folding-threshold=2 -S | FileCheck %s
3
James Molloy4de84dd2015-11-04 15:28:04 +00004; This test should succeed and end up if-converted.
James Molloy4de84dd2015-11-04 15:28:04 +00005define void @test_simple(i32* %p, i32 %a, i32 %b) {
Sanjay Patel28249272017-04-09 16:16:32 +00006; CHECK-LABEL: @test_simple(
7; CHECK-NEXT: entry:
Sanjay Patel28249272017-04-09 16:16:32 +00008; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i32 [[A:%.*]], 0
Sanjay Patel33439f92017-04-12 15:11:33 +00009; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[B:%.*]], 0
Sanjay Patel28249272017-04-09 16:16:32 +000010; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X2]], true
11; CHECK-NEXT: [[TMP2:%.*]] = or i1 [[TMP0]], [[TMP1]]
12; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]]
13; CHECK: [[NOT_X2:%.*]] = xor i1 [[X2]], true
14; CHECK-NEXT: [[DOT:%.*]] = zext i1 [[NOT_X2]] to i32
15; CHECK-NEXT: store i32 [[DOT]], i32* [[P:%.*]], align 4
16; CHECK-NEXT: br label [[TMP4]]
17; CHECK: ret void
18;
James Molloy4de84dd2015-11-04 15:28:04 +000019entry:
20 %x1 = icmp eq i32 %a, 0
21 br i1 %x1, label %fallthrough, label %yes1
22
23yes1:
24 store i32 0, i32* %p
25 br label %fallthrough
26
27fallthrough:
28 %x2 = icmp eq i32 %b, 0
29 br i1 %x2, label %end, label %yes2
30
31yes2:
32 store i32 1, i32* %p
33 br label %end
34
35end:
36 ret void
37}
38
Craig Topper1cb0e5a2017-04-20 22:57:36 +000039; This is the same as test_simple, but the branch target order has been swapped
40; TODO: This test should succeed and end up if-converted.
41define void @test_simple_commuted(i32* %p, i32 %a, i32 %b) {
42; CHECK-LABEL: @test_simple_commuted(
43; CHECK-NEXT: entry:
44; CHECK-NEXT: [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
45; CHECK-NEXT: br i1 [[X1]], label [[YES1:%.*]], label [[FALLTHROUGH:%.*]]
46; CHECK: yes1:
47; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
48; CHECK-NEXT: br label [[FALLTHROUGH]]
49; CHECK: fallthrough:
50; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[B:%.*]], 0
51; CHECK-NEXT: br i1 [[X2]], label [[YES2:%.*]], label [[END:%.*]]
52; CHECK: yes2:
53; CHECK-NEXT: store i32 1, i32* [[P]], align 4
54; CHECK-NEXT: br label [[END]]
55; CHECK: end:
56; CHECK-NEXT: ret void
57;
58entry:
59 %x1 = icmp eq i32 %a, 0
60 br i1 %x1, label %yes1, label %fallthrough
61
62yes1:
63 store i32 0, i32* %p
64 br label %fallthrough
65
66fallthrough:
67 %x2 = icmp eq i32 %b, 0
68 br i1 %x2, label %yes2, label %end
69
70yes2:
71 store i32 1, i32* %p
72 br label %end
73
74end:
75 ret void
76}
77
James Molloy4de84dd2015-11-04 15:28:04 +000078; This test should entirely fold away, leaving one large basic block.
James Molloy4de84dd2015-11-04 15:28:04 +000079define void @test_recursive(i32* %p, i32 %a, i32 %b, i32 %c, i32 %d) {
Sanjay Patel28249272017-04-09 16:16:32 +000080; CHECK-LABEL: @test_recursive(
81; CHECK-NEXT: entry:
82; CHECK-NEXT: [[TMP0:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
83; CHECK-NEXT: [[X4:%.*]] = icmp eq i32 [[D:%.*]], 0
84; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[TMP0]], [[C:%.*]]
Sanjay Patel28249272017-04-09 16:16:32 +000085; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
Sanjay Patel33439f92017-04-12 15:11:33 +000086; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[X4]], true
Sanjay Patel28249272017-04-09 16:16:32 +000087; CHECK-NEXT: [[TMP4:%.*]] = or i1 [[TMP3]], [[TMP2]]
88; CHECK-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
89; CHECK: [[X3:%.*]] = icmp eq i32 [[C]], 0
90; CHECK-NEXT: [[NOT_X2:%.*]] = icmp ne i32 [[B]], 0
91; CHECK-NEXT: [[DOT:%.*]] = zext i1 [[NOT_X2]] to i32
92; CHECK-NEXT: [[DOT_:%.*]] = select i1 [[X3]], i32 [[DOT]], i32 2
93; CHECK-NEXT: [[DOT__:%.*]] = select i1 [[X4]], i32 [[DOT_]], i32 3
94; CHECK-NEXT: store i32 [[DOT__]], i32* [[P:%.*]], align 4
95; CHECK-NEXT: br label [[TMP6]]
96; CHECK: ret void
97;
James Molloy4de84dd2015-11-04 15:28:04 +000098entry:
99 %x1 = icmp eq i32 %a, 0
100 br i1 %x1, label %fallthrough, label %yes1
101
102yes1:
103 store i32 0, i32* %p
104 br label %fallthrough
105
106fallthrough:
107 %x2 = icmp eq i32 %b, 0
108 br i1 %x2, label %next, label %yes2
109
110yes2:
111 store i32 1, i32* %p
112 br label %next
113
114next:
115 %x3 = icmp eq i32 %c, 0
116 br i1 %x3, label %fallthrough2, label %yes3
117
118yes3:
119 store i32 2, i32* %p
120 br label %fallthrough2
121
122fallthrough2:
123 %x4 = icmp eq i32 %d, 0
124 br i1 %x4, label %end, label %yes4
125
126yes4:
127 store i32 3, i32* %p
128 br label %end
129
130
131end:
132 ret void
133}
134
James Molloy4de84dd2015-11-04 15:28:04 +0000135; The code in each diamond is too large - it won't be if-converted so our
136; heuristics should say no.
James Molloy4de84dd2015-11-04 15:28:04 +0000137define void @test_not_ifconverted(i32* %p, i32 %a, i32 %b) {
Sanjay Patel28249272017-04-09 16:16:32 +0000138; CHECK-LABEL: @test_not_ifconverted(
139; CHECK-NEXT: entry:
140; CHECK-NEXT: [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
141; CHECK-NEXT: br i1 [[X1]], label [[FALLTHROUGH:%.*]], label [[YES1:%.*]]
142; CHECK: yes1:
143; CHECK-NEXT: [[Y1:%.*]] = or i32 [[B:%.*]], 55
144; CHECK-NEXT: [[Y2:%.*]] = add i32 [[Y1]], 24
145; CHECK-NEXT: [[Y3:%.*]] = and i32 [[Y2]], 67
146; CHECK-NEXT: store i32 [[Y3]], i32* [[P:%.*]], align 4
147; CHECK-NEXT: br label [[FALLTHROUGH]]
148; CHECK: fallthrough:
149; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[B]], 0
150; CHECK-NEXT: br i1 [[X2]], label [[END:%.*]], label [[YES2:%.*]]
151; CHECK: yes2:
152; CHECK-NEXT: [[Z1:%.*]] = or i32 [[A]], 55
153; CHECK-NEXT: [[Z2:%.*]] = add i32 [[Z1]], 24
154; CHECK-NEXT: [[Z3:%.*]] = and i32 [[Z2]], 67
155; CHECK-NEXT: store i32 [[Z3]], i32* [[P]], align 4
156; CHECK-NEXT: br label [[END]]
157; CHECK: end:
158; CHECK-NEXT: ret void
159;
James Molloy4de84dd2015-11-04 15:28:04 +0000160entry:
161 %x1 = icmp eq i32 %a, 0
162 br i1 %x1, label %fallthrough, label %yes1
163
164yes1:
165 %y1 = or i32 %b, 55
166 %y2 = add i32 %y1, 24
167 %y3 = and i32 %y2, 67
168 store i32 %y3, i32* %p
169 br label %fallthrough
170
171fallthrough:
172 %x2 = icmp eq i32 %b, 0
173 br i1 %x2, label %end, label %yes2
174
175yes2:
176 %z1 = or i32 %a, 55
177 %z2 = add i32 %z1, 24
178 %z3 = and i32 %z2, 67
179 store i32 %z3, i32* %p
180 br label %end
181
182end:
183 ret void
184}
185
James Molloy4de84dd2015-11-04 15:28:04 +0000186; The store to %p clobbers the previous store, so if-converting this would
187; be illegal.
James Molloy4de84dd2015-11-04 15:28:04 +0000188define void @test_aliasing1(i32* %p, i32 %a, i32 %b) {
Sanjay Patel28249272017-04-09 16:16:32 +0000189; CHECK-LABEL: @test_aliasing1(
190; CHECK-NEXT: entry:
191; CHECK-NEXT: [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
192; CHECK-NEXT: br i1 [[X1]], label [[FALLTHROUGH:%.*]], label [[YES1:%.*]]
193; CHECK: yes1:
194; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
195; CHECK-NEXT: br label [[FALLTHROUGH]]
196; CHECK: fallthrough:
197; CHECK-NEXT: [[Y1:%.*]] = load i32, i32* [[P]], align 4
198; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[Y1]], 0
199; CHECK-NEXT: br i1 [[X2]], label [[END:%.*]], label [[YES2:%.*]]
200; CHECK: yes2:
201; CHECK-NEXT: store i32 1, i32* [[P]], align 4
202; CHECK-NEXT: br label [[END]]
203; CHECK: end:
204; CHECK-NEXT: ret void
205;
James Molloy4de84dd2015-11-04 15:28:04 +0000206entry:
207 %x1 = icmp eq i32 %a, 0
208 br i1 %x1, label %fallthrough, label %yes1
209
210yes1:
211 store i32 0, i32* %p
212 br label %fallthrough
213
214fallthrough:
215 %y1 = load i32, i32* %p
216 %x2 = icmp eq i32 %y1, 0
217 br i1 %x2, label %end, label %yes2
218
219yes2:
220 store i32 1, i32* %p
221 br label %end
222
223end:
224 ret void
225}
226
James Molloy4de84dd2015-11-04 15:28:04 +0000227; The load from %q aliases with %p, so if-converting this would be illegal.
James Molloy4de84dd2015-11-04 15:28:04 +0000228define void @test_aliasing2(i32* %p, i32* %q, i32 %a, i32 %b) {
Sanjay Patel28249272017-04-09 16:16:32 +0000229; CHECK-LABEL: @test_aliasing2(
230; CHECK-NEXT: entry:
231; CHECK-NEXT: [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
232; CHECK-NEXT: br i1 [[X1]], label [[FALLTHROUGH:%.*]], label [[YES1:%.*]]
233; CHECK: yes1:
234; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
235; CHECK-NEXT: br label [[FALLTHROUGH]]
236; CHECK: fallthrough:
237; CHECK-NEXT: [[Y1:%.*]] = load i32, i32* [[Q:%.*]], align 4
238; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[Y1]], 0
239; CHECK-NEXT: br i1 [[X2]], label [[END:%.*]], label [[YES2:%.*]]
240; CHECK: yes2:
241; CHECK-NEXT: store i32 1, i32* [[P]], align 4
242; CHECK-NEXT: br label [[END]]
243; CHECK: end:
244; CHECK-NEXT: ret void
245;
James Molloy4de84dd2015-11-04 15:28:04 +0000246entry:
247 %x1 = icmp eq i32 %a, 0
248 br i1 %x1, label %fallthrough, label %yes1
249
250yes1:
251 store i32 0, i32* %p
252 br label %fallthrough
253
254fallthrough:
255 %y1 = load i32, i32* %q
256 %x2 = icmp eq i32 %y1, 0
257 br i1 %x2, label %end, label %yes2
258
259yes2:
260 store i32 1, i32* %p
261 br label %end
262
263end:
264 ret void
265}
266
267declare void @f()
268
James Molloy4de84dd2015-11-04 15:28:04 +0000269; This should get if-converted.
James Molloy4de84dd2015-11-04 15:28:04 +0000270define i32 @test_diamond_simple(i32* %p, i32* %q, i32 %a, i32 %b) {
Sanjay Patel28249272017-04-09 16:16:32 +0000271; CHECK-LABEL: @test_diamond_simple(
272; CHECK-NEXT: entry:
273; CHECK-NEXT: [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
274; CHECK-NEXT: [[Z1:%.*]] = add i32 [[A]], [[B:%.*]]
275; CHECK-NEXT: [[Z2:%.*]] = select i1 [[X1]], i32 [[Z1]], i32 0
276; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[B]], 0
277; CHECK-NEXT: [[Z3:%.*]] = sub i32 [[Z2]], [[B]]
278; CHECK-NEXT: [[Z4:%.*]] = select i1 [[X2]], i32 [[Z3]], i32 3
279; CHECK-NEXT: [[TMP0:%.*]] = or i32 [[A]], [[B]]
280; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0
281; CHECK-NEXT: br i1 [[TMP1]], label [[TMP3:%.*]], label [[TMP2:%.*]]
282; CHECK: [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[X2]], i32 [[Z2]], i32 1
283; CHECK-NEXT: store i32 [[SIMPLIFYCFG_MERGE]], i32* [[P:%.*]], align 4
284; CHECK-NEXT: br label [[TMP3]]
285; CHECK: ret i32 [[Z4]]
286;
James Molloy4de84dd2015-11-04 15:28:04 +0000287entry:
288 %x1 = icmp eq i32 %a, 0
289 br i1 %x1, label %no1, label %yes1
290
291yes1:
292 store i32 0, i32* %p
293 br label %fallthrough
294
295no1:
296 %z1 = add i32 %a, %b
297 br label %fallthrough
298
299fallthrough:
300 %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
301 %x2 = icmp eq i32 %b, 0
302 br i1 %x2, label %no2, label %yes2
303
304yes2:
305 store i32 1, i32* %p
306 br label %end
307
308no2:
309 %z3 = sub i32 %z2, %b
310 br label %end
311
312end:
313 %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
314 ret i32 %z4
315}
316
James Molloy4de84dd2015-11-04 15:28:04 +0000317; Now there is a call to f() in the bottom branch. The store in the first
318; branch would now be reordered with respect to the call if we if-converted,
319; so we must not.
James Molloy4de84dd2015-11-04 15:28:04 +0000320define i32 @test_diamond_alias3(i32* %p, i32* %q, i32 %a, i32 %b) {
Sanjay Patel28249272017-04-09 16:16:32 +0000321; CHECK-LABEL: @test_diamond_alias3(
322; CHECK-NEXT: entry:
323; CHECK-NEXT: [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
324; CHECK-NEXT: br i1 [[X1]], label [[NO1:%.*]], label [[YES1:%.*]]
325; CHECK: yes1:
326; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
327; CHECK-NEXT: br label [[FALLTHROUGH:%.*]]
328; CHECK: no1:
329; CHECK-NEXT: call void @f()
330; CHECK-NEXT: [[Z1:%.*]] = add i32 [[A]], [[B:%.*]]
331; CHECK-NEXT: br label [[FALLTHROUGH]]
332; CHECK: fallthrough:
333; CHECK-NEXT: [[Z2:%.*]] = phi i32 [ [[Z1]], [[NO1]] ], [ 0, [[YES1]] ]
334; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[B]], 0
335; CHECK-NEXT: br i1 [[X2]], label [[NO2:%.*]], label [[YES2:%.*]]
336; CHECK: yes2:
337; CHECK-NEXT: store i32 1, i32* [[P]], align 4
338; CHECK-NEXT: br label [[END:%.*]]
339; CHECK: no2:
340; CHECK-NEXT: call void @f()
341; CHECK-NEXT: [[Z3:%.*]] = sub i32 [[Z2]], [[B]]
342; CHECK-NEXT: br label [[END]]
343; CHECK: end:
344; CHECK-NEXT: [[Z4:%.*]] = phi i32 [ [[Z3]], [[NO2]] ], [ 3, [[YES2]] ]
345; CHECK-NEXT: ret i32 [[Z4]]
346;
James Molloy4de84dd2015-11-04 15:28:04 +0000347entry:
348 %x1 = icmp eq i32 %a, 0
349 br i1 %x1, label %no1, label %yes1
350
351yes1:
352 store i32 0, i32* %p
353 br label %fallthrough
354
355no1:
356 call void @f()
357 %z1 = add i32 %a, %b
358 br label %fallthrough
359
360fallthrough:
361 %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
362 %x2 = icmp eq i32 %b, 0
363 br i1 %x2, label %no2, label %yes2
364
365yes2:
366 store i32 1, i32* %p
367 br label %end
368
369no2:
370 call void @f()
371 %z3 = sub i32 %z2, %b
372 br label %end
373
374end:
375 %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
376 ret i32 %z4
377}