[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Transforms / SimplifyCFG / merge-cond-stores.ll
blobe9a3e608ea2922886ecc6d1ad8571109dbff231a
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:       2:
14 ; CHECK-NEXT:    [[NOT_X2:%.*]] = xor i1 [[X2]], true
15 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = zext i1 [[NOT_X2]] to i32
16 ; CHECK-NEXT:    store i32 [[SPEC_SELECT]], i32* [[P:%.*]], align 4
17 ; CHECK-NEXT:    br label [[TMP3]]
18 ; CHECK:       3:
19 ; CHECK-NEXT:    ret void
21 entry:
22   %x1 = icmp eq i32 %a, 0
23   br i1 %x1, label %fallthrough, label %yes1
25 yes1:
26   store i32 0, i32* %p
27   br label %fallthrough
29 fallthrough:
30   %x2 = icmp eq i32 %b, 0
31   br i1 %x2, label %end, label %yes2
33 yes2:
34   store i32 1, i32* %p
35   br label %end
37 end:
38   ret void
41 ; This is the same as test_simple, but the branch target order has been swapped
42 define void @test_simple_commuted(i32* %p, i32 %a, i32 %b) {
43 ; CHECK-LABEL: @test_simple_commuted(
44 ; CHECK-NEXT:  entry:
45 ; CHECK-NEXT:    [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
46 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[B:%.*]], 0
47 ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[X1]], [[X2]]
48 ; CHECK-NEXT:    br i1 [[TMP0]], label [[TMP1:%.*]], label [[TMP2:%.*]]
49 ; CHECK:       1:
50 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = zext i1 [[X2]] to i32
51 ; CHECK-NEXT:    store i32 [[SPEC_SELECT]], i32* [[P:%.*]], align 4
52 ; CHECK-NEXT:    br label [[TMP2]]
53 ; CHECK:       2:
54 ; CHECK-NEXT:    ret void
56 entry:
57   %x1 = icmp eq i32 %a, 0
58   br i1 %x1, label %yes1, label %fallthrough
60 yes1:
61   store i32 0, i32* %p
62   br label %fallthrough
64 fallthrough:
65   %x2 = icmp eq i32 %b, 0
66   br i1 %x2, label %yes2, label %end
68 yes2:
69   store i32 1, i32* %p
70   br label %end
72 end:
73   ret void
76 ; This test should entirely fold away, leaving one large basic block.
77 define void @test_recursive(i32* %p, i32 %a, i32 %b, i32 %c, i32 %d) {
78 ; CHECK-LABEL: @test_recursive(
79 ; CHECK-NEXT:  entry:
80 ; CHECK-NEXT:    [[TMP0:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
81 ; CHECK-NEXT:    [[X4:%.*]] = icmp eq i32 [[D:%.*]], 0
82 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[TMP0]], [[C:%.*]]
83 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
84 ; CHECK-NEXT:    [[TMP3:%.*]] = xor i1 [[X4]], true
85 ; CHECK-NEXT:    [[TMP4:%.*]] = or i1 [[TMP2]], [[TMP3]]
86 ; CHECK-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]]
87 ; CHECK:       5:
88 ; CHECK-NEXT:    [[X3:%.*]] = icmp eq i32 [[C]], 0
89 ; CHECK-NEXT:    [[X2:%.*]] = icmp ne i32 [[B]], 0
90 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = zext i1 [[X2]] to i32
91 ; CHECK-NEXT:    [[SPEC_SELECT1:%.*]] = select i1 [[X3]], i32 [[SPEC_SELECT]], i32 2
92 ; CHECK-NEXT:    [[SPEC_SELECT2:%.*]] = select i1 [[X4]], i32 [[SPEC_SELECT1]], i32 3
93 ; CHECK-NEXT:    store i32 [[SPEC_SELECT2]], i32* [[P:%.*]], align 4
94 ; CHECK-NEXT:    br label [[TMP6]]
95 ; CHECK:       6:
96 ; CHECK-NEXT:    ret void
98 entry:
99   %x1 = icmp eq i32 %a, 0
100   br i1 %x1, label %fallthrough, label %yes1
102 yes1:
103   store i32 0, i32* %p
104   br label %fallthrough
106 fallthrough:
107   %x2 = icmp eq i32 %b, 0
108   br i1 %x2, label %next, label %yes2
110 yes2:
111   store i32 1, i32* %p
112   br label %next
114 next:
115   %x3 = icmp eq i32 %c, 0
116   br i1 %x3, label %fallthrough2, label %yes3
118 yes3:
119   store i32 2, i32* %p
120   br label %fallthrough2
122 fallthrough2:
123   %x4 = icmp eq i32 %d, 0
124   br i1 %x4, label %end, label %yes4
126 yes4:
127   store i32 3, i32* %p
128   br label %end
131 end:
132   ret void
135 ; The code in each diamond is too large - it won't be if-converted so our
136 ; heuristics should say no.
137 define void @test_not_ifconverted(i32* %p, i32 %a, i32 %b) {
138 ; 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
160 entry:
161   %x1 = icmp eq i32 %a, 0
162   br i1 %x1, label %fallthrough, label %yes1
164 yes1:
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
171 fallthrough:
172   %x2 = icmp eq i32 %b, 0
173   br i1 %x2, label %end, label %yes2
175 yes2:
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
182 end:
183   ret void
186 ; The store to %p clobbers the previous store, so if-converting this would
187 ; be illegal.
188 define void @test_aliasing1(i32* %p, i32 %a, i32 %b) {
189 ; 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
206 entry:
207   %x1 = icmp eq i32 %a, 0
208   br i1 %x1, label %fallthrough, label %yes1
210 yes1:
211   store i32 0, i32* %p
212   br label %fallthrough
214 fallthrough:
215   %y1 = load i32, i32* %p
216   %x2 = icmp eq i32 %y1, 0
217   br i1 %x2, label %end, label %yes2
219 yes2:
220   store i32 1, i32* %p
221   br label %end
223 end:
224   ret void
227 ; The load from %q aliases with %p, so if-converting this would be illegal.
228 define void @test_aliasing2(i32* %p, i32* %q, i32 %a, i32 %b) {
229 ; 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
246 entry:
247   %x1 = icmp eq i32 %a, 0
248   br i1 %x1, label %fallthrough, label %yes1
250 yes1:
251   store i32 0, i32* %p
252   br label %fallthrough
254 fallthrough:
255   %y1 = load i32, i32* %q
256   %x2 = icmp eq i32 %y1, 0
257   br i1 %x2, label %end, label %yes2
259 yes2:
260   store i32 1, i32* %p
261   br label %end
263 end:
264   ret void
267 declare void @f()
269 ; This should get if-converted.
270 define i32 @test_diamond_simple(i32* %p, i32* %q, i32 %a, i32 %b) {
271 ; CHECK-LABEL: @test_diamond_simple(
272 ; CHECK-NEXT:  entry:
273 ; CHECK-NEXT:    [[X1:%.*]] = icmp eq i32 [[A:%.*]], 0
274 ; CHECK-NEXT:    [[Z2:%.*]] = select i1 [[X1]], i32 [[B:%.*]], i32 0
275 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[B]], 0
276 ; CHECK-NEXT:    [[Z4:%.*]] = select i1 [[X2]], i32 [[Z2]], i32 3
277 ; CHECK-NEXT:    [[TMP0:%.*]] = or i32 [[A]], [[B]]
278 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0
279 ; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP3:%.*]], label [[TMP2:%.*]]
280 ; CHECK:       2:
281 ; CHECK-NEXT:    [[SIMPLIFYCFG_MERGE:%.*]] = select i1 [[X2]], i32 [[Z2]], i32 1
282 ; CHECK-NEXT:    store i32 [[SIMPLIFYCFG_MERGE]], i32* [[P:%.*]], align 4
283 ; CHECK-NEXT:    br label [[TMP3]]
284 ; CHECK:       3:
285 ; CHECK-NEXT:    ret i32 [[Z4]]
287 entry:
288   %x1 = icmp eq i32 %a, 0
289   br i1 %x1, label %no1, label %yes1
291 yes1:
292   store i32 0, i32* %p
293   br label %fallthrough
295 no1:
296   %z1 = add i32 %a, %b
297   br label %fallthrough
299 fallthrough:
300   %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
301   %x2 = icmp eq i32 %b, 0
302   br i1 %x2, label %no2, label %yes2
304 yes2:
305   store i32 1, i32* %p
306   br label %end
308 no2:
309   %z3 = sub i32 %z2, %b
310   br label %end
312 end:
313   %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
314   ret i32 %z4
317 ; 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.
320 define i32 @test_diamond_alias3(i32* %p, i32* %q, i32 %a, i32 %b) {
321 ; 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]]
347 entry:
348   %x1 = icmp eq i32 %a, 0
349   br i1 %x1, label %no1, label %yes1
351 yes1:
352   store i32 0, i32* %p
353   br label %fallthrough
355 no1:
356   call void @f()
357   %z1 = add i32 %a, %b
358   br label %fallthrough
360 fallthrough:
361   %z2 = phi i32 [ %z1, %no1 ], [ 0, %yes1 ]
362   %x2 = icmp eq i32 %b, 0
363   br i1 %x2, label %no2, label %yes2
365 yes2:
366   store i32 1, i32* %p
367   br label %end
369 no2:
370   call void @f()
371   %z3 = sub i32 %z2, %b
372   br label %end
374 end:
375   %z4 = phi i32 [ %z3, %no2 ], [ 3, %yes2 ]
376   ret i32 %z4
379 ; This test has an outer if over the two triangles. This requires creating a new BB to hold the store.
380 define void @test_outer_if(i32* %p, i32 %a, i32 %b, i32 %c) {
381 ; CHECK-LABEL: @test_outer_if(
382 ; CHECK-NEXT:  entry:
383 ; CHECK-NEXT:    [[X3:%.*]] = icmp eq i32 [[C:%.*]], 0
384 ; CHECK-NEXT:    br i1 [[X3]], label [[END:%.*]], label [[CONTINUE:%.*]]
385 ; CHECK:       continue:
386 ; CHECK-NEXT:    [[X1:%.*]] = icmp ne i32 [[A:%.*]], 0
387 ; CHECK-NEXT:    [[X2:%.*]] = icmp eq i32 [[B:%.*]], 0
388 ; CHECK-NEXT:    [[TMP0:%.*]] = xor i1 [[X2]], true
389 ; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[X1]], [[TMP0]]
390 ; CHECK-NEXT:    br i1 [[TMP1]], label [[TMP2:%.*]], label [[END]]
391 ; CHECK:       2:
392 ; CHECK-NEXT:    [[NOT_X2:%.*]] = xor i1 [[X2]], true
393 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = zext i1 [[NOT_X2]] to i32
394 ; CHECK-NEXT:    store i32 [[SPEC_SELECT]], i32* [[P:%.*]], align 4
395 ; CHECK-NEXT:    br label [[END]]
396 ; CHECK:       end:
397 ; CHECK-NEXT:    ret void
399 entry:
400   %x3 = icmp eq i32 %c, 0
401   br i1 %x3, label %end, label %continue
402 continue:
403   %x1 = icmp eq i32 %a, 0
404   br i1 %x1, label %fallthrough, label %yes1
405 yes1:
406   store i32 0, i32* %p
407   br label %fallthrough
408   fallthrough:
409   %x2 = icmp eq i32 %b, 0
410   br i1 %x2, label %end, label %yes2
411 yes2:
412   store i32 1, i32* %p
413   br label %end
414 end:
415   ret void