blob: baec5244219ead3c75842a2d7bcd7a7217b87a86 [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:
8; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[B:%.*]], 0
9; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i32 [[A:%.*]], 0
10; 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
James Molloy4de84dd2015-11-04 15:28:04 +000039; This test should entirely fold away, leaving one large basic block.
James Molloy4de84dd2015-11-04 15:28:04 +000040define void @test_recursive(i32* %p, i32 %a, i32 %b, i32 %c, i32 %d) {
Sanjay Patel28249272017-04-09 16:16:32 +000041; CHECK-LABEL: @test_recursive(
42; CHECK-NEXT: entry:
43; CHECK-NEXT: [[TMP0:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
44; CHECK-NEXT: [[X4:%.*]] = icmp eq i32 [[D:%.*]], 0
45; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[TMP0]], [[C:%.*]]
46; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[X4]], true
47; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
48; CHECK-NEXT: [[TMP4:%.*]] = or i1 [[TMP3]], [[TMP2]]
49; CHECK-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
50; CHECK: [[X3:%.*]] = icmp eq i32 [[C]], 0
51; CHECK-NEXT: [[NOT_X2:%.*]] = icmp ne i32 [[B]], 0
52; CHECK-NEXT: [[DOT:%.*]] = zext i1 [[NOT_X2]] to i32
53; CHECK-NEXT: [[DOT_:%.*]] = select i1 [[X3]], i32 [[DOT]], i32 2
54; CHECK-NEXT: [[DOT__:%.*]] = select i1 [[X4]], i32 [[DOT_]], i32 3
55; CHECK-NEXT: store i32 [[DOT__]], i32* [[P:%.*]], align 4
56; CHECK-NEXT: br label [[TMP6]]
57; CHECK: ret void
58;
James Molloy4de84dd2015-11-04 15:28:04 +000059entry:
60 %x1 = icmp eq i32 %a, 0
61 br i1 %x1, label %fallthrough, label %yes1
62
63yes1:
64 store i32 0, i32* %p
65 br label %fallthrough
66
67fallthrough:
68 %x2 = icmp eq i32 %b, 0
69 br i1 %x2, label %next, label %yes2
70
71yes2:
72 store i32 1, i32* %p
73 br label %next
74
75next:
76 %x3 = icmp eq i32 %c, 0
77 br i1 %x3, label %fallthrough2, label %yes3
78
79yes3:
80 store i32 2, i32* %p
81 br label %fallthrough2
82
83fallthrough2:
84 %x4 = icmp eq i32 %d, 0
85 br i1 %x4, label %end, label %yes4
86
87yes4:
88 store i32 3, i32* %p
89 br label %end
90
91
92end:
93 ret void
94}
95
James Molloy4de84dd2015-11-04 15:28:04 +000096; The code in each diamond is too large - it won't be if-converted so our
97; heuristics should say no.
James Molloy4de84dd2015-11-04 15:28:04 +000098define void @test_not_ifconverted(i32* %p, i32 %a, i32 %b) {
Sanjay Patel28249272017-04-09 16:16:32 +000099; CHECK-LABEL: @test_not_ifconverted(
100; CHECK-NEXT: entry:
101; CHECK-NEXT: [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
102; CHECK-NEXT: br i1 [[X1]], label [[FALLTHROUGH:%.*]], label [[YES1:%.*]]
103; CHECK: yes1:
104; CHECK-NEXT: [[Y1:%.*]] = or i32 [[B:%.*]], 55
105; CHECK-NEXT: [[Y2:%.*]] = add i32 [[Y1]], 24
106; CHECK-NEXT: [[Y3:%.*]] = and i32 [[Y2]], 67
107; CHECK-NEXT: store i32 [[Y3]], i32* [[P:%.*]], align 4
108; CHECK-NEXT: br label [[FALLTHROUGH]]
109; CHECK: fallthrough:
110; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[B]], 0
111; CHECK-NEXT: br i1 [[X2]], label [[END:%.*]], label [[YES2:%.*]]
112; CHECK: yes2:
113; CHECK-NEXT: [[Z1:%.*]] = or i32 [[A]], 55
114; CHECK-NEXT: [[Z2:%.*]] = add i32 [[Z1]], 24
115; CHECK-NEXT: [[Z3:%.*]] = and i32 [[Z2]], 67
116; CHECK-NEXT: store i32 [[Z3]], i32* [[P]], align 4
117; CHECK-NEXT: br label [[END]]
118; CHECK: end:
119; CHECK-NEXT: ret void
120;
James Molloy4de84dd2015-11-04 15:28:04 +0000121entry:
122 %x1 = icmp eq i32 %a, 0
123 br i1 %x1, label %fallthrough, label %yes1
124
125yes1:
126 %y1 = or i32 %b, 55
127 %y2 = add i32 %y1, 24
128 %y3 = and i32 %y2, 67
129 store i32 %y3, i32* %p
130 br label %fallthrough
131
132fallthrough:
133 %x2 = icmp eq i32 %b, 0
134 br i1 %x2, label %end, label %yes2
135
136yes2:
137 %z1 = or i32 %a, 55
138 %z2 = add i32 %z1, 24
139 %z3 = and i32 %z2, 67
140 store i32 %z3, i32* %p
141 br label %end
142
143end:
144 ret void
145}
146
James Molloy4de84dd2015-11-04 15:28:04 +0000147; The store to %p clobbers the previous store, so if-converting this would
148; be illegal.
James Molloy4de84dd2015-11-04 15:28:04 +0000149define void @test_aliasing1(i32* %p, i32 %a, i32 %b) {
Sanjay Patel28249272017-04-09 16:16:32 +0000150; CHECK-LABEL: @test_aliasing1(
151; CHECK-NEXT: entry:
152; CHECK-NEXT: [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
153; CHECK-NEXT: br i1 [[X1]], label [[FALLTHROUGH:%.*]], label [[YES1:%.*]]
154; CHECK: yes1:
155; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
156; CHECK-NEXT: br label [[FALLTHROUGH]]
157; CHECK: fallthrough:
158; CHECK-NEXT: [[Y1:%.*]] = load i32, i32* [[P]], align 4
159; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[Y1]], 0
160; CHECK-NEXT: br i1 [[X2]], label [[END:%.*]], label [[YES2:%.*]]
161; CHECK: yes2:
162; CHECK-NEXT: store i32 1, i32* [[P]], align 4
163; CHECK-NEXT: br label [[END]]
164; CHECK: end:
165; CHECK-NEXT: ret void
166;
James Molloy4de84dd2015-11-04 15:28:04 +0000167entry:
168 %x1 = icmp eq i32 %a, 0
169 br i1 %x1, label %fallthrough, label %yes1
170
171yes1:
172 store i32 0, i32* %p
173 br label %fallthrough
174
175fallthrough:
176 %y1 = load i32, i32* %p
177 %x2 = icmp eq i32 %y1, 0
178 br i1 %x2, label %end, label %yes2
179
180yes2:
181 store i32 1, i32* %p
182 br label %end
183
184end:
185 ret void
186}
187
James Molloy4de84dd2015-11-04 15:28:04 +0000188; The load from %q aliases with %p, so if-converting this would be illegal.
James Molloy4de84dd2015-11-04 15:28:04 +0000189define void @test_aliasing2(i32* %p, i32* %q, i32 %a, i32 %b) {
Sanjay Patel28249272017-04-09 16:16:32 +0000190; CHECK-LABEL: @test_aliasing2(
191; CHECK-NEXT: entry:
192; CHECK-NEXT: [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
193; CHECK-NEXT: br i1 [[X1]], label [[FALLTHROUGH:%.*]], label [[YES1:%.*]]
194; CHECK: yes1:
195; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
196; CHECK-NEXT: br label [[FALLTHROUGH]]
197; CHECK: fallthrough:
198; CHECK-NEXT: [[Y1:%.*]] = load i32, i32* [[Q:%.*]], align 4
199; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[Y1]], 0
200; CHECK-NEXT: br i1 [[X2]], label [[END:%.*]], label [[YES2:%.*]]
201; CHECK: yes2:
202; CHECK-NEXT: store i32 1, i32* [[P]], align 4
203; CHECK-NEXT: br label [[END]]
204; CHECK: end:
205; CHECK-NEXT: ret void
206;
James Molloy4de84dd2015-11-04 15:28:04 +0000207entry:
208 %x1 = icmp eq i32 %a, 0
209 br i1 %x1, label %fallthrough, label %yes1
210
211yes1:
212 store i32 0, i32* %p
213 br label %fallthrough
214
215fallthrough:
216 %y1 = load i32, i32* %q
217 %x2 = icmp eq i32 %y1, 0
218 br i1 %x2, label %end, label %yes2
219
220yes2:
221 store i32 1, i32* %p
222 br label %end
223
224end:
225 ret void
226}
227
228declare void @f()
229
James Molloy4de84dd2015-11-04 15:28:04 +0000230; This should get if-converted.
James Molloy4de84dd2015-11-04 15:28:04 +0000231define i32 @test_diamond_simple(i32* %p, i32* %q, i32 %a, i32 %b) {
Sanjay Patel28249272017-04-09 16:16:32 +0000232; CHECK-LABEL: @test_diamond_simple(
233; CHECK-NEXT: entry:
234; CHECK-NEXT: [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
235; CHECK-NEXT: [[Z1:%.*]] = add i32 [[A]], [[B:%.*]]
236; CHECK-NEXT: [[Z2:%.*]] = select i1 [[X1]], i32 [[Z1]], i32 0
237; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[B]], 0
238; CHECK-NEXT: [[Z3:%.*]] = sub i32 [[Z2]], [[B]]
239; CHECK-NEXT: [[Z4:%.*]] = select i1 [[X2]], i32 [[Z3]], i32 3
240; CHECK-NEXT: [[TMP0:%.*]] = or i32 [[A]], [[B]]
241; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0
242; CHECK-NEXT: br i1 [[TMP1]], label [[TMP3:%.*]], label [[TMP2:%.*]]
243; CHECK: [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[X2]], i32 [[Z2]], i32 1
244; CHECK-NEXT: store i32 [[SIMPLIFYCFG_MERGE]], i32* [[P:%.*]], align 4
245; CHECK-NEXT: br label [[TMP3]]
246; CHECK: ret i32 [[Z4]]
247;
James Molloy4de84dd2015-11-04 15:28:04 +0000248entry:
249 %x1 = icmp eq i32 %a, 0
250 br i1 %x1, label %no1, label %yes1
251
252yes1:
253 store i32 0, i32* %p
254 br label %fallthrough
255
256no1:
257 %z1 = add i32 %a, %b
258 br label %fallthrough
259
260fallthrough:
261 %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
262 %x2 = icmp eq i32 %b, 0
263 br i1 %x2, label %no2, label %yes2
264
265yes2:
266 store i32 1, i32* %p
267 br label %end
268
269no2:
270 %z3 = sub i32 %z2, %b
271 br label %end
272
273end:
274 %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
275 ret i32 %z4
276}
277
James Molloy4de84dd2015-11-04 15:28:04 +0000278; Now there is a call to f() in the bottom branch. The store in the first
279; branch would now be reordered with respect to the call if we if-converted,
280; so we must not.
James Molloy4de84dd2015-11-04 15:28:04 +0000281define i32 @test_diamond_alias3(i32* %p, i32* %q, i32 %a, i32 %b) {
Sanjay Patel28249272017-04-09 16:16:32 +0000282; CHECK-LABEL: @test_diamond_alias3(
283; CHECK-NEXT: entry:
284; CHECK-NEXT: [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
285; CHECK-NEXT: br i1 [[X1]], label [[NO1:%.*]], label [[YES1:%.*]]
286; CHECK: yes1:
287; CHECK-NEXT: store i32 0, i32* [[P:%.*]], align 4
288; CHECK-NEXT: br label [[FALLTHROUGH:%.*]]
289; CHECK: no1:
290; CHECK-NEXT: call void @f()
291; CHECK-NEXT: [[Z1:%.*]] = add i32 [[A]], [[B:%.*]]
292; CHECK-NEXT: br label [[FALLTHROUGH]]
293; CHECK: fallthrough:
294; CHECK-NEXT: [[Z2:%.*]] = phi i32 [ [[Z1]], [[NO1]] ], [ 0, [[YES1]] ]
295; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[B]], 0
296; CHECK-NEXT: br i1 [[X2]], label [[NO2:%.*]], label [[YES2:%.*]]
297; CHECK: yes2:
298; CHECK-NEXT: store i32 1, i32* [[P]], align 4
299; CHECK-NEXT: br label [[END:%.*]]
300; CHECK: no2:
301; CHECK-NEXT: call void @f()
302; CHECK-NEXT: [[Z3:%.*]] = sub i32 [[Z2]], [[B]]
303; CHECK-NEXT: br label [[END]]
304; CHECK: end:
305; CHECK-NEXT: [[Z4:%.*]] = phi i32 [ [[Z3]], [[NO2]] ], [ 3, [[YES2]] ]
306; CHECK-NEXT: ret i32 [[Z4]]
307;
James Molloy4de84dd2015-11-04 15:28:04 +0000308entry:
309 %x1 = icmp eq i32 %a, 0
310 br i1 %x1, label %no1, label %yes1
311
312yes1:
313 store i32 0, i32* %p
314 br label %fallthrough
315
316no1:
317 call void @f()
318 %z1 = add i32 %a, %b
319 br label %fallthrough
320
321fallthrough:
322 %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
323 %x2 = icmp eq i32 %b, 0
324 br i1 %x2, label %no2, label %yes2
325
326yes2:
327 store i32 1, i32* %p
328 br label %end
329
330no2:
331 call void @f()
332 %z3 = sub i32 %z2, %b
333 br label %end
334
335end:
336 %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
337 ret i32 %z4
338}