[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / Transforms / SimplifyCFG / merge-cond-stores.ll
blobfd629c8cec50327a1c2df3dbfaffdb535d1c8158
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -simplifycfg -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:    [[X1:%.*]] = icmp ne i32 [[A:%.*]], 0
9 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[B:%.*]], 0
10 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X2]], true
11 ; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[X1]], [[TMP0]]
12 ; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP3:%.*]]
13 ; CHECK:         [[NOT_X2:%.*]] = xor i1 [[X2]], true
14 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = zext i1 [[NOT_X2]] to i32
15 ; CHECK-NEXT:    store i32 [[SPEC_SELECT]], i32* [[P:%.*]], align 4
16 ; CHECK-NEXT:    br label [[TMP3]]
17 ; CHECK:         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:%.*]] = icmp eq i32 [[A:%.*]], 0
44 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[B:%.*]], 0
45 ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[X1]], [[X2]]
46 ; CHECK-NEXT:    br i1 [[TMP0]], label [[TMP1:%.*]], label [[TMP2:%.*]]
47 ; CHECK:         [[SPEC_SELECT:%.*]] = zext i1 [[X2]] to i32
48 ; CHECK-NEXT:    store i32 [[SPEC_SELECT]], i32* [[P:%.*]], align 4
49 ; CHECK-NEXT:    br label [[TMP2]]
50 ; CHECK:         ret void
52 entry:
53   %x1 = icmp eq i32 %a, 0
54   br i1 %x1, label %yes1, label %fallthrough
56 yes1:
57   store i32 0, i32* %p
58   br label %fallthrough
60 fallthrough:
61   %x2 = icmp eq i32 %b, 0
62   br i1 %x2, label %yes2, label %end
64 yes2:
65   store i32 1, i32* %p
66   br label %end
68 end:
69   ret void
72 ; This test should entirely fold away, leaving one large basic block.
73 define void @test_recursive(i32* %p, i32 %a, i32 %b, i32 %c, i32 %d) {
74 ; CHECK-LABEL: @test_recursive(
75 ; CHECK-NEXT:  entry:
76 ; CHECK-NEXT:    [[TMP0:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
77 ; CHECK-NEXT:    [[X4:%.*]] = icmp eq i32 [[D:%.*]], 0
78 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[TMP0]], [[C:%.*]]
79 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
80 ; CHECK-NEXT:    [[TMP3:%.*]] = xor i1 [[X4]], true
81 ; CHECK-NEXT:    [[TMP4:%.*]] = or i1 [[TMP2]], [[TMP3]]
82 ; CHECK-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
83 ; CHECK:         [[X3:%.*]] = icmp eq i32 [[C]], 0
84 ; CHECK-NEXT:    [[X2:%.*]] = icmp ne i32 [[B]], 0
85 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = zext i1 [[X2]] to i32
86 ; CHECK-NEXT:    [[SPEC_SELECT1:%.*]] = select i1 [[X3]], i32 [[SPEC_SELECT]], i32 2
87 ; CHECK-NEXT:    [[SPEC_SELECT2:%.*]] = select i1 [[X4]], i32 [[SPEC_SELECT1]], i32 3
88 ; CHECK-NEXT:    store i32 [[SPEC_SELECT2]], i32* [[P:%.*]], align 4
89 ; CHECK-NEXT:    br label [[TMP6]]
90 ; CHECK:         ret void
92 entry:
93   %x1 = icmp eq i32 %a, 0
94   br i1 %x1, label %fallthrough, label %yes1
96 yes1:
97   store i32 0, i32* %p
98   br label %fallthrough
100 fallthrough:
101   %x2 = icmp eq i32 %b, 0
102   br i1 %x2, label %next, label %yes2
104 yes2:
105   store i32 1, i32* %p
106   br label %next
108 next:
109   %x3 = icmp eq i32 %c, 0
110   br i1 %x3, label %fallthrough2, label %yes3
112 yes3:
113   store i32 2, i32* %p
114   br label %fallthrough2
116 fallthrough2:
117   %x4 = icmp eq i32 %d, 0
118   br i1 %x4, label %end, label %yes4
120 yes4:
121   store i32 3, i32* %p
122   br label %end
125 end:
126   ret void
129 ; The code in each diamond is too large - it won't be if-converted so our
130 ; heuristics should say no.
131 define void @test_not_ifconverted(i32* %p, i32 %a, i32 %b) {
132 ; CHECK-LABEL: @test_not_ifconverted(
133 ; CHECK-NEXT:  entry:
134 ; CHECK-NEXT:    [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
135 ; CHECK-NEXT:    br i1 [[X1]], label [[FALLTHROUGH:%.*]], label [[YES1:%.*]]
136 ; CHECK:       yes1:
137 ; CHECK-NEXT:    [[Y1:%.*]] = or i32 [[B:%.*]], 55
138 ; CHECK-NEXT:    [[Y2:%.*]] = add i32 [[Y1]], 24
139 ; CHECK-NEXT:    [[Y3:%.*]] = and i32 [[Y2]], 67
140 ; CHECK-NEXT:    store i32 [[Y3]], i32* [[P:%.*]], align 4
141 ; CHECK-NEXT:    br label [[FALLTHROUGH]]
142 ; CHECK:       fallthrough:
143 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[B]], 0
144 ; CHECK-NEXT:    br i1 [[X2]], label [[END:%.*]], label [[YES2:%.*]]
145 ; CHECK:       yes2:
146 ; CHECK-NEXT:    [[Z1:%.*]] = or i32 [[A]], 55
147 ; CHECK-NEXT:    [[Z2:%.*]] = add i32 [[Z1]], 24
148 ; CHECK-NEXT:    [[Z3:%.*]] = and i32 [[Z2]], 67
149 ; CHECK-NEXT:    store i32 [[Z3]], i32* [[P]], align 4
150 ; CHECK-NEXT:    br label [[END]]
151 ; CHECK:       end:
152 ; CHECK-NEXT:    ret void
154 entry:
155   %x1 = icmp eq i32 %a, 0
156   br i1 %x1, label %fallthrough, label %yes1
158 yes1:
159   %y1 = or i32 %b, 55
160   %y2 = add i32 %y1, 24
161   %y3 = and i32 %y2, 67
162   store i32 %y3, i32* %p
163   br label %fallthrough
165 fallthrough:
166   %x2 = icmp eq i32 %b, 0
167   br i1 %x2, label %end, label %yes2
169 yes2:
170   %z1 = or i32 %a, 55
171   %z2 = add i32 %z1, 24
172   %z3 = and i32 %z2, 67
173   store i32 %z3, i32* %p
174   br label %end
176 end:
177   ret void
180 ; The store to %p clobbers the previous store, so if-converting this would
181 ; be illegal.
182 define void @test_aliasing1(i32* %p, i32 %a, i32 %b) {
183 ; CHECK-LABEL: @test_aliasing1(
184 ; CHECK-NEXT:  entry:
185 ; CHECK-NEXT:    [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
186 ; CHECK-NEXT:    br i1 [[X1]], label [[FALLTHROUGH:%.*]], label [[YES1:%.*]]
187 ; CHECK:       yes1:
188 ; CHECK-NEXT:    store i32 0, i32* [[P:%.*]], align 4
189 ; CHECK-NEXT:    br label [[FALLTHROUGH]]
190 ; CHECK:       fallthrough:
191 ; CHECK-NEXT:    [[Y1:%.*]] = load i32, i32* [[P]], align 4
192 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[Y1]], 0
193 ; CHECK-NEXT:    br i1 [[X2]], label [[END:%.*]], label [[YES2:%.*]]
194 ; CHECK:       yes2:
195 ; CHECK-NEXT:    store i32 1, i32* [[P]], align 4
196 ; CHECK-NEXT:    br label [[END]]
197 ; CHECK:       end:
198 ; CHECK-NEXT:    ret void
200 entry:
201   %x1 = icmp eq i32 %a, 0
202   br i1 %x1, label %fallthrough, label %yes1
204 yes1:
205   store i32 0, i32* %p
206   br label %fallthrough
208 fallthrough:
209   %y1 = load i32, i32* %p
210   %x2 = icmp eq i32 %y1, 0
211   br i1 %x2, label %end, label %yes2
213 yes2:
214   store i32 1, i32* %p
215   br label %end
217 end:
218   ret void
221 ; The load from %q aliases with %p, so if-converting this would be illegal.
222 define void @test_aliasing2(i32* %p, i32* %q, i32 %a, i32 %b) {
223 ; CHECK-LABEL: @test_aliasing2(
224 ; CHECK-NEXT:  entry:
225 ; CHECK-NEXT:    [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
226 ; CHECK-NEXT:    br i1 [[X1]], label [[FALLTHROUGH:%.*]], label [[YES1:%.*]]
227 ; CHECK:       yes1:
228 ; CHECK-NEXT:    store i32 0, i32* [[P:%.*]], align 4
229 ; CHECK-NEXT:    br label [[FALLTHROUGH]]
230 ; CHECK:       fallthrough:
231 ; CHECK-NEXT:    [[Y1:%.*]] = load i32, i32* [[Q:%.*]], align 4
232 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[Y1]], 0
233 ; CHECK-NEXT:    br i1 [[X2]], label [[END:%.*]], label [[YES2:%.*]]
234 ; CHECK:       yes2:
235 ; CHECK-NEXT:    store i32 1, i32* [[P]], align 4
236 ; CHECK-NEXT:    br label [[END]]
237 ; CHECK:       end:
238 ; CHECK-NEXT:    ret void
240 entry:
241   %x1 = icmp eq i32 %a, 0
242   br i1 %x1, label %fallthrough, label %yes1
244 yes1:
245   store i32 0, i32* %p
246   br label %fallthrough
248 fallthrough:
249   %y1 = load i32, i32* %q
250   %x2 = icmp eq i32 %y1, 0
251   br i1 %x2, label %end, label %yes2
253 yes2:
254   store i32 1, i32* %p
255   br label %end
257 end:
258   ret void
261 declare void @f()
263 ; This should get if-converted.
264 define i32 @test_diamond_simple(i32* %p, i32* %q, i32 %a, i32 %b) {
265 ; CHECK-LABEL: @test_diamond_simple(
266 ; CHECK-NEXT:  entry:
267 ; CHECK-NEXT:    [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
268 ; CHECK-NEXT:    [[Z2:%.*]] = select i1 [[X1]], i32 [[B:%.*]], i32 0
269 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[B]], 0
270 ; CHECK-NEXT:    [[Z4:%.*]] = select i1 [[X2]], i32 [[Z2]], i32 3
271 ; CHECK-NEXT:    [[TMP0:%.*]] = or i32 [[A]], [[B]]
272 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0
273 ; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP3:%.*]], label [[TMP2:%.*]]
274 ; CHECK:         [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[X2]], i32 [[Z2]], i32 1
275 ; CHECK-NEXT:    store i32 [[SIMPLIFYCFG_MERGE]], i32* [[P:%.*]], align 4
276 ; CHECK-NEXT:    br label [[TMP3]]
277 ; CHECK:         ret i32 [[Z4]]
279 entry:
280   %x1 = icmp eq i32 %a, 0
281   br i1 %x1, label %no1, label %yes1
283 yes1:
284   store i32 0, i32* %p
285   br label %fallthrough
287 no1:
288   %z1 = add i32 %a, %b
289   br label %fallthrough
291 fallthrough:
292   %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
293   %x2 = icmp eq i32 %b, 0
294   br i1 %x2, label %no2, label %yes2
296 yes2:
297   store i32 1, i32* %p
298   br label %end
300 no2:
301   %z3 = sub i32 %z2, %b
302   br label %end
304 end:
305   %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
306   ret i32 %z4
309 ; Now there is a call to f() in the bottom branch. The store in the first
310 ; branch would now be reordered with respect to the call if we if-converted,
311 ; so we must not.
312 define i32 @test_diamond_alias3(i32* %p, i32* %q, i32 %a, i32 %b) {
313 ; CHECK-LABEL: @test_diamond_alias3(
314 ; CHECK-NEXT:  entry:
315 ; CHECK-NEXT:    [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
316 ; CHECK-NEXT:    br i1 [[X1]], label [[NO1:%.*]], label [[YES1:%.*]]
317 ; CHECK:       yes1:
318 ; CHECK-NEXT:    store i32 0, i32* [[P:%.*]], align 4
319 ; CHECK-NEXT:    br label [[FALLTHROUGH:%.*]]
320 ; CHECK:       no1:
321 ; CHECK-NEXT:    call void @f()
322 ; CHECK-NEXT:    [[Z1:%.*]] = add i32 [[A]], [[B:%.*]]
323 ; CHECK-NEXT:    br label [[FALLTHROUGH]]
324 ; CHECK:       fallthrough:
325 ; CHECK-NEXT:    [[Z2:%.*]] = phi i32 [ [[Z1]], [[NO1]] ], [ 0, [[YES1]] ]
326 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[B]], 0
327 ; CHECK-NEXT:    br i1 [[X2]], label [[NO2:%.*]], label [[YES2:%.*]]
328 ; CHECK:       yes2:
329 ; CHECK-NEXT:    store i32 1, i32* [[P]], align 4
330 ; CHECK-NEXT:    br label [[END:%.*]]
331 ; CHECK:       no2:
332 ; CHECK-NEXT:    call void @f()
333 ; CHECK-NEXT:    [[Z3:%.*]] = sub i32 [[Z2]], [[B]]
334 ; CHECK-NEXT:    br label [[END]]
335 ; CHECK:       end:
336 ; CHECK-NEXT:    [[Z4:%.*]] = phi i32 [ [[Z3]], [[NO2]] ], [ 3, [[YES2]] ]
337 ; CHECK-NEXT:    ret i32 [[Z4]]
339 entry:
340   %x1 = icmp eq i32 %a, 0
341   br i1 %x1, label %no1, label %yes1
343 yes1:
344   store i32 0, i32* %p
345   br label %fallthrough
347 no1:
348   call void @f()
349   %z1 = add i32 %a, %b
350   br label %fallthrough
352 fallthrough:
353   %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
354   %x2 = icmp eq i32 %b, 0
355   br i1 %x2, label %no2, label %yes2
357 yes2:
358   store i32 1, i32* %p
359   br label %end
361 no2:
362   call void @f()
363   %z3 = sub i32 %z2, %b
364   br label %end
366 end:
367   %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
368   ret i32 %z4
371 ; This test has an outer if over the two triangles. This requires creating a new BB to hold the store.
372 define void @test_outer_if(i32* %p, i32 %a, i32 %b, i32 %c) {
373 ; CHECK-LABEL: @test_outer_if(
374 ; CHECK-NEXT:  entry:
375 ; CHECK-NEXT:    [[X3:%.*]] = icmp eq i32 [[C:%.*]], 0
376 ; CHECK-NEXT:    br i1 [[X3]], label [[END:%.*]], label [[CONTINUE:%.*]]
377 ; CHECK:       continue:
378 ; CHECK-NEXT:    [[X1:%.*]] = icmp ne i32 [[A:%.*]], 0
379 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[B:%.*]], 0
380 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X2]], true
381 ; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[X1]], [[TMP0]]
382 ; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[END]]
383 ; CHECK:         [[NOT_X2:%.*]] = xor i1 [[X2]], true
384 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = zext i1 [[NOT_X2]] to i32
385 ; CHECK-NEXT:    store i32 [[SPEC_SELECT]], i32* [[P:%.*]], align 4
386 ; CHECK-NEXT:    br label [[END]]
387 ; CHECK:       end:
388 ; CHECK-NEXT:    ret void
390 entry:
391   %x3 = icmp eq i32 %c, 0
392   br i1 %x3, label %end, label %continue
393 continue:
394   %x1 = icmp eq i32 %a, 0
395   br i1 %x1, label %fallthrough, label %yes1
396 yes1:
397   store i32 0, i32* %p
398   br label %fallthrough
399   fallthrough:
400   %x2 = icmp eq i32 %b, 0
401   br i1 %x2, label %end, label %yes2
402 yes2:
403   store i32 1, i32* %p
404   br label %end
405 end:
406   ret void