[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / merge-cond-stores.ll
blob71aac1c4d48bbbf87f6d4b826480141288043e66
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -instcombine < %s -simplifycfg-merge-cond-stores=true -simplifycfg-merge-cond-stores-aggressively=false -phi-node-folding-threshold=2 -S | FileCheck %s
4 ; This test should succeed and end up if-converted.
5 define void @test_simple(i32* %p, i32 %a, i32 %b) {
6 ; CHECK-LABEL: @test_simple(
7 ; CHECK-NEXT:  entry:
8 ; CHECK-NEXT:    [[TMP0:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
9 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0
10 ; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP3:%.*]], label [[TMP2:%.*]]
11 ; CHECK:       2:
12 ; CHECK-NEXT:    [[X2:%.*]] = icmp ne i32 [[B]], 0
13 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = zext i1 [[X2]] to i32
14 ; CHECK-NEXT:    store i32 [[SPEC_SELECT]], i32* [[P:%.*]], align 4
15 ; CHECK-NEXT:    br label [[TMP3]]
16 ; CHECK:       3:
17 ; CHECK-NEXT:    ret void
19 entry:
20   %x1 = icmp eq i32 %a, 0
21   br i1 %x1, label %fallthrough, label %yes1
23 yes1:
24   store i32 0, i32* %p
25   br label %fallthrough
27 fallthrough:
28   %x2 = icmp eq i32 %b, 0
29   br i1 %x2, label %end, label %yes2
31 yes2:
32   store i32 1, i32* %p
33   br label %end
35 end:
36   ret void
39 ; This is the same as test_simple, but the branch target order has been swapped
40 define void @test_simple_commuted(i32* %p, i32 %a, i32 %b) {
41 ; CHECK-LABEL: @test_simple_commuted(
42 ; CHECK-NEXT:  entry:
43 ; CHECK-NEXT:    [[X1_NOT:%.*]] = icmp eq i32 [[A:%.*]], 0
44 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[B:%.*]], 0
45 ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[X1_NOT]], [[X2]]
46 ; CHECK-NEXT:    br i1 [[TMP0]], label [[TMP1:%.*]], label [[TMP2:%.*]]
47 ; CHECK:       1:
48 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = zext i1 [[X2]] to i32
49 ; CHECK-NEXT:    store i32 [[SPEC_SELECT]], i32* [[P:%.*]], align 4
50 ; CHECK-NEXT:    br label [[TMP2]]
51 ; CHECK:       2:
52 ; CHECK-NEXT:    ret void
54 entry:
55   %x1 = icmp eq i32 %a, 0
56   br i1 %x1, label %yes1, label %fallthrough
58 yes1:
59   store i32 0, i32* %p
60   br label %fallthrough
62 fallthrough:
63   %x2 = icmp eq i32 %b, 0
64   br i1 %x2, label %yes2, label %end
66 yes2:
67   store i32 1, i32* %p
68   br label %end
70 end:
71   ret void
74 ; This test should entirely fold away, leaving one large basic block.
75 define void @test_recursive(i32* %p, i32 %a, i32 %b, i32 %c, i32 %d) {
76 ; CHECK-LABEL: @test_recursive(
77 ; CHECK-NEXT:  entry:
78 ; CHECK-NEXT:    [[TMP0:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
79 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[TMP0]], [[C:%.*]]
80 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[D:%.*]]
81 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
82 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]]
83 ; CHECK:       4:
84 ; CHECK-NEXT:    [[X4:%.*]] = icmp eq i32 [[D]], 0
85 ; CHECK-NEXT:    [[X3:%.*]] = icmp eq i32 [[C]], 0
86 ; CHECK-NEXT:    [[X2:%.*]] = icmp ne i32 [[B]], 0
87 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = zext i1 [[X2]] to i32
88 ; CHECK-NEXT:    [[SPEC_SELECT1:%.*]] = select i1 [[X3]], i32 [[SPEC_SELECT]], i32 2
89 ; CHECK-NEXT:    [[SPEC_SELECT2:%.*]] = select i1 [[X4]], i32 [[SPEC_SELECT1]], i32 3
90 ; CHECK-NEXT:    store i32 [[SPEC_SELECT2]], i32* [[P:%.*]], align 4
91 ; CHECK-NEXT:    br label [[TMP5]]
92 ; CHECK:       5:
93 ; CHECK-NEXT:    ret void
95 entry:
96   %x1 = icmp eq i32 %a, 0
97   br i1 %x1, label %fallthrough, label %yes1
99 yes1:
100   store i32 0, i32* %p
101   br label %fallthrough
103 fallthrough:
104   %x2 = icmp eq i32 %b, 0
105   br i1 %x2, label %next, label %yes2
107 yes2:
108   store i32 1, i32* %p
109   br label %next
111 next:
112   %x3 = icmp eq i32 %c, 0
113   br i1 %x3, label %fallthrough2, label %yes3
115 yes3:
116   store i32 2, i32* %p
117   br label %fallthrough2
119 fallthrough2:
120   %x4 = icmp eq i32 %d, 0
121   br i1 %x4, label %end, label %yes4
123 yes4:
124   store i32 3, i32* %p
125   br label %end
128 end:
129   ret void
132 ; The code in each diamond is too large - it won't be if-converted so our
133 ; heuristics should say no.
134 define void @test_not_ifconverted(i32* %p, i32 %a, i32 %b) {
135 ; CHECK-LABEL: @test_not_ifconverted(
136 ; CHECK-NEXT:  entry:
137 ; CHECK-NEXT:    [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
138 ; CHECK-NEXT:    br i1 [[X1]], label [[FALLTHROUGH:%.*]], label [[YES1:%.*]]
139 ; CHECK:       yes1:
140 ; CHECK-NEXT:    [[Y1:%.*]] = or i32 [[B:%.*]], 55
141 ; CHECK-NEXT:    [[Y2:%.*]] = add i32 [[Y1]], 24
142 ; CHECK-NEXT:    [[Y3:%.*]] = and i32 [[Y2]], 67
143 ; CHECK-NEXT:    store i32 [[Y3]], i32* [[P:%.*]], align 4
144 ; CHECK-NEXT:    br label [[FALLTHROUGH]]
145 ; CHECK:       fallthrough:
146 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[B]], 0
147 ; CHECK-NEXT:    br i1 [[X2]], label [[END:%.*]], label [[YES2:%.*]]
148 ; CHECK:       yes2:
149 ; CHECK-NEXT:    [[Z1:%.*]] = or i32 [[A]], 55
150 ; CHECK-NEXT:    [[Z2:%.*]] = add i32 [[Z1]], 24
151 ; CHECK-NEXT:    [[Z3:%.*]] = and i32 [[Z2]], 67
152 ; CHECK-NEXT:    store i32 [[Z3]], i32* [[P]], align 4
153 ; CHECK-NEXT:    br label [[END]]
154 ; CHECK:       end:
155 ; CHECK-NEXT:    ret void
157 entry:
158   %x1 = icmp eq i32 %a, 0
159   br i1 %x1, label %fallthrough, label %yes1
161 yes1:
162   %y1 = or i32 %b, 55
163   %y2 = add i32 %y1, 24
164   %y3 = and i32 %y2, 67
165   store i32 %y3, i32* %p
166   br label %fallthrough
168 fallthrough:
169   %x2 = icmp eq i32 %b, 0
170   br i1 %x2, label %end, label %yes2
172 yes2:
173   %z1 = or i32 %a, 55
174   %z2 = add i32 %z1, 24
175   %z3 = and i32 %z2, 67
176   store i32 %z3, i32* %p
177   br label %end
179 end:
180   ret void
183 ; The store to %p clobbers the previous store, so if-converting this would
184 ; be illegal.
185 define void @test_aliasing1(i32* %p, i32 %a, i32 %b) {
186 ; CHECK-LABEL: @test_aliasing1(
187 ; CHECK-NEXT:  entry:
188 ; CHECK-NEXT:    [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
189 ; CHECK-NEXT:    br i1 [[X1]], label [[FALLTHROUGH:%.*]], label [[YES1:%.*]]
190 ; CHECK:       yes1:
191 ; CHECK-NEXT:    store i32 0, i32* [[P:%.*]], align 4
192 ; CHECK-NEXT:    br label [[FALLTHROUGH]]
193 ; CHECK:       fallthrough:
194 ; CHECK-NEXT:    [[Y1:%.*]] = load i32, i32* [[P]], align 4
195 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[Y1]], 0
196 ; CHECK-NEXT:    br i1 [[X2]], label [[END:%.*]], label [[YES2:%.*]]
197 ; CHECK:       yes2:
198 ; CHECK-NEXT:    store i32 1, i32* [[P]], align 4
199 ; CHECK-NEXT:    br label [[END]]
200 ; CHECK:       end:
201 ; CHECK-NEXT:    ret void
203 entry:
204   %x1 = icmp eq i32 %a, 0
205   br i1 %x1, label %fallthrough, label %yes1
207 yes1:
208   store i32 0, i32* %p
209   br label %fallthrough
211 fallthrough:
212   %y1 = load i32, i32* %p
213   %x2 = icmp eq i32 %y1, 0
214   br i1 %x2, label %end, label %yes2
216 yes2:
217   store i32 1, i32* %p
218   br label %end
220 end:
221   ret void
224 ; The load from %q aliases with %p, so if-converting this would be illegal.
225 define void @test_aliasing2(i32* %p, i32* %q, i32 %a, i32 %b) {
226 ; CHECK-LABEL: @test_aliasing2(
227 ; CHECK-NEXT:  entry:
228 ; CHECK-NEXT:    [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
229 ; CHECK-NEXT:    br i1 [[X1]], label [[FALLTHROUGH:%.*]], label [[YES1:%.*]]
230 ; CHECK:       yes1:
231 ; CHECK-NEXT:    store i32 0, i32* [[P:%.*]], align 4
232 ; CHECK-NEXT:    br label [[FALLTHROUGH]]
233 ; CHECK:       fallthrough:
234 ; CHECK-NEXT:    [[Y1:%.*]] = load i32, i32* [[Q:%.*]], align 4
235 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[Y1]], 0
236 ; CHECK-NEXT:    br i1 [[X2]], label [[END:%.*]], label [[YES2:%.*]]
237 ; CHECK:       yes2:
238 ; CHECK-NEXT:    store i32 1, i32* [[P]], align 4
239 ; CHECK-NEXT:    br label [[END]]
240 ; CHECK:       end:
241 ; CHECK-NEXT:    ret void
243 entry:
244   %x1 = icmp eq i32 %a, 0
245   br i1 %x1, label %fallthrough, label %yes1
247 yes1:
248   store i32 0, i32* %p
249   br label %fallthrough
251 fallthrough:
252   %y1 = load i32, i32* %q
253   %x2 = icmp eq i32 %y1, 0
254   br i1 %x2, label %end, label %yes2
256 yes2:
257   store i32 1, i32* %p
258   br label %end
260 end:
261   ret void
264 declare void @f()
266 ; This should get if-converted.
267 define i32 @test_diamond_simple(i32* %p, i32* %q, i32 %a, i32 %b) {
268 ; CHECK-LABEL: @test_diamond_simple(
269 ; CHECK-NEXT:  entry:
270 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[B:%.*]], 0
271 ; CHECK-NEXT:    [[TMP0:%.*]] = or i32 [[B]], [[A:%.*]]
272 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0
273 ; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP3:%.*]], label [[TMP2:%.*]]
274 ; CHECK:       2:
275 ; CHECK-NEXT:    [[NOT_X2:%.*]] = xor i1 [[X2]], true
276 ; CHECK-NEXT:    [[SIMPLIFYCFG_MERGE:%.*]] = zext i1 [[NOT_X2]] to i32
277 ; CHECK-NEXT:    store i32 [[SIMPLIFYCFG_MERGE]], i32* [[P:%.*]], align 4
278 ; CHECK-NEXT:    br label [[TMP3]]
279 ; CHECK:       3:
280 ; CHECK-NEXT:    [[Z4:%.*]] = select i1 [[X2]], i32 0, i32 3
281 ; CHECK-NEXT:    ret i32 [[Z4]]
283 entry:
284   %x1 = icmp eq i32 %a, 0
285   br i1 %x1, label %no1, label %yes1
287 yes1:
288   store i32 0, i32* %p
289   br label %fallthrough
291 no1:
292   %z1 = add i32 %a, %b
293   br label %fallthrough
295 fallthrough:
296   %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
297   %x2 = icmp eq i32 %b, 0
298   br i1 %x2, label %no2, label %yes2
300 yes2:
301   store i32 1, i32* %p
302   br label %end
304 no2:
305   %z3 = sub i32 %z2, %b
306   br label %end
308 end:
309   %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
310   ret i32 %z4
313 ; Now there is a call to f() in the bottom branch. The store in the first
314 ; branch would now be reordered with respect to the call if we if-converted,
315 ; so we must not.
316 define i32 @test_diamond_alias3(i32* %p, i32* %q, i32 %a, i32 %b) {
317 ; CHECK-LABEL: @test_diamond_alias3(
318 ; CHECK-NEXT:  entry:
319 ; CHECK-NEXT:    [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
320 ; CHECK-NEXT:    br i1 [[X1]], label [[NO1:%.*]], label [[YES1:%.*]]
321 ; CHECK:       yes1:
322 ; CHECK-NEXT:    store i32 0, i32* [[P:%.*]], align 4
323 ; CHECK-NEXT:    br label [[FALLTHROUGH:%.*]]
324 ; CHECK:       no1:
325 ; CHECK-NEXT:    call void @f()
326 ; CHECK-NEXT:    [[Z1:%.*]] = add i32 [[A]], [[B:%.*]]
327 ; CHECK-NEXT:    br label [[FALLTHROUGH]]
328 ; CHECK:       fallthrough:
329 ; CHECK-NEXT:    [[Z2:%.*]] = phi i32 [ [[Z1]], [[NO1]] ], [ 0, [[YES1]] ]
330 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[B]], 0
331 ; CHECK-NEXT:    br i1 [[X2]], label [[NO2:%.*]], label [[YES2:%.*]]
332 ; CHECK:       yes2:
333 ; CHECK-NEXT:    store i32 1, i32* [[P]], align 4
334 ; CHECK-NEXT:    br label [[END:%.*]]
335 ; CHECK:       no2:
336 ; CHECK-NEXT:    call void @f()
337 ; CHECK-NEXT:    [[Z3:%.*]] = sub i32 [[Z2]], [[B]]
338 ; CHECK-NEXT:    br label [[END]]
339 ; CHECK:       end:
340 ; CHECK-NEXT:    [[Z4:%.*]] = phi i32 [ [[Z3]], [[NO2]] ], [ 3, [[YES2]] ]
341 ; CHECK-NEXT:    ret i32 [[Z4]]
343 entry:
344   %x1 = icmp eq i32 %a, 0
345   br i1 %x1, label %no1, label %yes1
347 yes1:
348   store i32 0, i32* %p
349   br label %fallthrough
351 no1:
352   call void @f()
353   %z1 = add i32 %a, %b
354   br label %fallthrough
356 fallthrough:
357   %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
358   %x2 = icmp eq i32 %b, 0
359   br i1 %x2, label %no2, label %yes2
361 yes2:
362   store i32 1, i32* %p
363   br label %end
365 no2:
366   call void @f()
367   %z3 = sub i32 %z2, %b
368   br label %end
370 end:
371   %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
372   ret i32 %z4
375 ; This test has an outer if over the two triangles. This requires creating a new BB to hold the store.
376 define void @test_outer_if(i32* %p, i32 %a, i32 %b, i32 %c) {
377 ; CHECK-LABEL: @test_outer_if(
378 ; CHECK-NEXT:  entry:
379 ; CHECK-NEXT:    [[X3:%.*]] = icmp eq i32 [[C:%.*]], 0
380 ; CHECK-NEXT:    br i1 [[X3]], label [[END:%.*]], label [[CONTINUE:%.*]]
381 ; CHECK:       continue:
382 ; CHECK-NEXT:    [[TMP0:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
383 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0
384 ; CHECK-NEXT:    br i1 [[TMP1]], label [[END]], label [[TMP2:%.*]]
385 ; CHECK:       2:
386 ; CHECK-NEXT:    [[X2:%.*]] = icmp ne i32 [[B]], 0
387 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = zext i1 [[X2]] to i32
388 ; CHECK-NEXT:    store i32 [[SPEC_SELECT]], i32* [[P:%.*]], align 4
389 ; CHECK-NEXT:    br label [[END]]
390 ; CHECK:       end:
391 ; CHECK-NEXT:    ret void
393 entry:
394   %x3 = icmp eq i32 %c, 0
395   br i1 %x3, label %end, label %continue
396 continue:
397   %x1 = icmp eq i32 %a, 0
398   br i1 %x1, label %fallthrough, label %yes1
399 yes1:
400   store i32 0, i32* %p
401   br label %fallthrough
402   fallthrough:
403   %x2 = icmp eq i32 %b, 0
404   br i1 %x2, label %end, label %yes2
405 yes2:
406   store i32 1, i32* %p
407   br label %end
408 end:
409   ret void