[PowerPC] Eliminate compares - add i32 sext/zext handling for SETULT/SETUGT
[llvm-core.git] / test / Transforms / CorrelatedValuePropagation / range.ll
blobe38e9e6f47aac138c6c8297e6a0d6ab50613935a
1 ; RUN: opt -correlated-propagation -S < %s | FileCheck %s
3 declare i32 @foo()
5 define i32 @test1(i32 %a) nounwind {
6   %a.off = add i32 %a, -8
7   %cmp = icmp ult i32 %a.off, 8
8   br i1 %cmp, label %then, label %else
10 then:
11   %dead = icmp eq i32 %a, 7
12   br i1 %dead, label %end, label %else
14 else:
15   ret i32 1
17 end:
18   ret i32 2
20 ; CHECK-LABEL: @test1(
21 ; CHECK: then:
22 ; CHECK-NEXT: br i1 false, label %end, label %else
25 define i32 @test2(i32 %a) nounwind {
26   %a.off = add i32 %a, -8
27   %cmp = icmp ult i32 %a.off, 8
28   br i1 %cmp, label %then, label %else
30 then:
31   %dead = icmp ugt i32 %a, 15
32   br i1 %dead, label %end, label %else
34 else:
35   ret i32 1
37 end:
38   ret i32 2
40 ; CHECK-LABEL: @test2(
41 ; CHECK: then:
42 ; CHECK-NEXT: br i1 false, label %end, label %else
45 ; CHECK-LABEL: @test3(
46 define i32 @test3(i32 %c) nounwind {
47   %cmp = icmp slt i32 %c, 2
48   br i1 %cmp, label %if.then, label %if.end
50 if.then:
51   ret i32 1
53 if.end:
54   %cmp1 = icmp slt i32 %c, 3
55   br i1 %cmp1, label %if.then2, label %if.end8
57 ; CHECK: if.then2
58 if.then2:
59   %cmp2 = icmp eq i32 %c, 2
60 ; CHECK: br i1 true
61   br i1 %cmp2, label %if.then4, label %if.end6
63 ; CHECK: if.end6
64 if.end6:
65   ret i32 2
67 if.then4:
68   ret i32 3
70 if.end8:
71   ret i32 4
74 ; CHECK-LABEL: @test4(
75 define i32 @test4(i32 %c) nounwind {
76   switch i32 %c, label %sw.default [
77     i32 1, label %sw.bb
78     i32 2, label %sw.bb
79     i32 4, label %sw.bb
80   ]
82 ; CHECK: sw.bb
83 sw.bb:
84   %cmp = icmp sge i32 %c, 1
85 ; CHECK: br i1 true
86   br i1 %cmp, label %if.then, label %if.end
88 if.then:
89   br label %return
91 if.end:
92   br label %return
94 sw.default:
95   br label %return
97 return:
98   %retval.0 = phi i32 [ 42, %sw.default ], [ 4, %if.then ], [ 9, %if.end ]
99   ret i32 %retval.0
102 ; CHECK-LABEL: @test5(
103 define i1 @test5(i32 %c) nounwind {
104   %cmp = icmp slt i32 %c, 5
105   br i1 %cmp, label %if.then, label %if.end
107 if.then:
108   %cmp1 = icmp eq i32 %c, 4
109   br i1 %cmp1, label %if.end, label %if.end8
111 if.end:
112   ret i1 true
114 if.end8:
115   %cmp2 = icmp eq i32 %c, 3
116   %cmp3 = icmp eq i32 %c, 4
117   %cmp4 = icmp eq i32 %c, 6
118 ; CHECK: %or = or i1 false, false
119   %or = or i1 %cmp3, %cmp4
120 ; CHECK: ret i1 %cmp2
121   ret i1 %cmp2
124 ; CHECK-LABEL: @test6(
125 define i1 @test6(i32 %c) nounwind {
126   %cmp = icmp ule i32 %c, 7
127   br i1 %cmp, label %if.then, label %if.end
129 if.then:
130 ; CHECK: icmp eq i32 %c, 6
131 ; CHECK: br i1
132   switch i32 %c, label %if.end [
133     i32 6, label %sw.bb
134     i32 8, label %sw.bb
135   ]
137 if.end:
138   ret i1 true
140 sw.bb:
141   %cmp2 = icmp eq i32 %c, 6
142 ; CHECK: ret i1 true
143   ret i1 %cmp2
146 ; CHECK-LABEL: @test7(
147 define i1 @test7(i32 %c) nounwind {
148 entry:
149  switch i32 %c, label %sw.default [
150    i32 6, label %sw.bb
151    i32 7, label %sw.bb
154 sw.bb:
155  ret i1 true
157 sw.default:
158  %cmp5 = icmp eq i32 %c, 5
159  %cmp6 = icmp eq i32 %c, 6
160  %cmp7 = icmp eq i32 %c, 7
161  %cmp8 = icmp eq i32 %c, 8
162 ; CHECK: %or = or i1 %cmp5, false
163  %or = or i1 %cmp5, %cmp6
164 ; CHECK: %or2 = or i1 false, %cmp8
165  %or2 = or i1 %cmp7, %cmp8
166  ret i1 false
169 define i1 @test8(i64* %p) {
170 ; CHECK-LABEL: @test8
171 ; CHECK: ret i1 false
172   %a = load i64, i64* %p, !range !{i64 4, i64 255}
173   %res = icmp eq i64 %a, 0
174   ret i1 %res
177 define i1 @test9(i64* %p) {
178 ; CHECK-LABEL: @test9
179 ; CHECK: ret i1 true
180   %a = load i64, i64* %p, !range !{i64 0, i64 1}
181   %res = icmp eq i64 %a, 0
182   ret i1 %res
185 define i1 @test10(i64* %p) {
186 ; CHECK-LABEL: @test10
187 ; CHECK: ret i1 false
188   %a = load i64, i64* %p, !range !{i64 4, i64 8, i64 15, i64 20}
189   %res = icmp eq i64 %a, 0
190   ret i1 %res
193 @g = external global i32
195 define i1 @test11() {
196 ; CHECK: @test11
197 ; CHECK: ret i1 true
198   %positive = load i32, i32* @g, !range !{i32 1, i32 2048}
199   %add = add i32 %positive, 1
200   %test = icmp sgt i32 %add, 0
201   br label %next
203 next:
204   ret i1 %test
207 define i32 @test12(i32 %a, i32 %b) {
208 ; CHECK-LABEL: @test12(
209 ; CHECK: then:
210 ; CHECK-NEXT: br i1 false, label %end, label %else
211   %cmp = icmp ult i32 %a, %b
212   br i1 %cmp, label %then, label %else
214 then:
215   %dead = icmp eq i32 %a, -1
216   br i1 %dead, label %end, label %else
218 else:
219   ret i32 1
221 end:
222   ret i32 2
225 define i32 @test12_swap(i32 %a, i32 %b) {
226 ; CHECK-LABEL: @test12_swap(
227 ; CHECK: then:
228 ; CHECK-NEXT: br i1 false, label %end, label %else
229   %cmp = icmp ugt i32 %b, %a
230   br i1 %cmp, label %then, label %else
232 then:
233   %dead = icmp eq i32 %a, -1
234   br i1 %dead, label %end, label %else
236 else:
237   ret i32 1
239 end:
240   ret i32 2
243 define i32 @test12_neg(i32 %a, i32 %b) {
244 ; The same as @test12 but the second check is on the false path
245 ; CHECK-LABEL: @test12_neg(
246 ; CHECK: else:
247 ; CHECK-NEXT: %alive = icmp eq i32 %a, -1
248   %cmp = icmp ult i32 %a, %b
249   br i1 %cmp, label %then, label %else
251 else:
252   %alive = icmp eq i32 %a, -1
253   br i1 %alive, label %end, label %then
255 then:
256   ret i32 1
258 end:
259   ret i32 2
262 define i32 @test12_signed(i32 %a, i32 %b) {
263 ; The same as @test12 but with signed comparison
264 ; CHECK-LABEL: @test12_signed(
265 ; CHECK: then:
266 ; CHECK-NEXT: br i1 false, label %end, label %else
267   %cmp = icmp slt i32 %a, %b
268   br i1 %cmp, label %then, label %else
270 then:
271   %dead = icmp eq i32 %a, 2147483647
272   br i1 %dead, label %end, label %else
274 else:
275   ret i32 1
277 end:
278   ret i32 2
281 define i32 @test13(i32 %a, i32 %b) {
282 ; CHECK-LABEL: @test13(
283 ; CHECK: then:
284 ; CHECK-NEXT: br i1 false, label %end, label %else
285   %a.off = add i32 %a, -8
286   %cmp = icmp ult i32 %a.off, %b
287   br i1 %cmp, label %then, label %else
289 then:
290   %dead = icmp eq i32 %a, 7
291   br i1 %dead, label %end, label %else
293 else:
294   ret i32 1
296 end:
297   ret i32 2
300 define i32 @test13_swap(i32 %a, i32 %b) {
301 ; CHECK-LABEL: @test13_swap(
302 ; CHECK: then:
303 ; CHECK-NEXT: br i1 false, label %end, label %else
304   %a.off = add i32 %a, -8
305   %cmp = icmp ugt i32 %b, %a.off
306   br i1 %cmp, label %then, label %else
308 then:
309   %dead = icmp eq i32 %a, 7
310   br i1 %dead, label %end, label %else
312 else:
313   ret i32 1
315 end:
316   ret i32 2
319 define i1 @test14_slt(i32 %a) {
320 ; CHECK-LABEL: @test14_slt(
321 ; CHECK: then:
322 ; CHECK-NEXT: %result = or i1 false, false
323   %a.off = add i32 %a, -8
324   %cmp = icmp slt i32 %a.off, 8
325   br i1 %cmp, label %then, label %else
327 then:
328   %dead.1 = icmp eq i32 %a, -2147483641
329   %dead.2 = icmp eq i32 %a, 16
330   %result = or i1 %dead.1, %dead.2
331   ret i1 %result
333 else:
334   ret i1 false
337 define i1 @test14_sle(i32 %a) {
338 ; CHECK-LABEL: @test14_sle(
339 ; CHECK: then:
340 ; CHECK-NEXT: %alive = icmp eq i32 %a, 16
341 ; CHECK-NEXT: %result = or i1 false, %alive
342   %a.off = add i32 %a, -8
343   %cmp = icmp sle i32 %a.off, 8
344   br i1 %cmp, label %then, label %else
346 then:
347   %dead = icmp eq i32 %a, -2147483641
348   %alive = icmp eq i32 %a, 16
349   %result = or i1 %dead, %alive
350   ret i1 %result
352 else:
353   ret i1 false
356 define i1 @test14_sgt(i32 %a) {
357 ; CHECK-LABEL: @test14_sgt(
358 ; CHECK: then:
359 ; CHECK-NEXT: %result = or i1 false, false
360   %a.off = add i32 %a, -8
361   %cmp = icmp sgt i32 %a.off, 8
362   br i1 %cmp, label %then, label %else
364 then:
365   %dead.1 = icmp eq i32 %a, -2147483640
366   %dead.2 = icmp eq i32 %a, 16
367   %result = or i1 %dead.1, %dead.2
368   ret i1 %result
370 else:
371   ret i1 false
374 define i1 @test14_sge(i32 %a) {
375 ; CHECK-LABEL: @test14_sge(
376 ; CHECK: then:
377 ; CHECK-NEXT: %alive = icmp eq i32 %a, 16
378 ; CHECK-NEXT: %result = or i1 false, %alive
379   %a.off = add i32 %a, -8
380   %cmp = icmp sge i32 %a.off, 8
381   br i1 %cmp, label %then, label %else
383 then:
384   %dead = icmp eq i32 %a, -2147483640
385   %alive = icmp eq i32 %a, 16
386   %result = or i1 %dead, %alive
387   ret i1 %result
389 else:
390   ret i1 false
393 define i1 @test14_ule(i32 %a) {
394 ; CHECK-LABEL: @test14_ule(
395 ; CHECK: then:
396 ; CHECK-NEXT: %alive = icmp eq i32 %a, 16
397 ; CHECK-NEXT: %result = or i1 false, %alive
398   %a.off = add i32 %a, -8
399   %cmp = icmp ule i32 %a.off, 8
400   br i1 %cmp, label %then, label %else
402 then:
403   %dead = icmp eq i32 %a, 7
404   %alive = icmp eq i32 %a, 16
405   %result = or i1 %dead, %alive
406   ret i1 %result
408 else:
409   ret i1 false
412 define i1 @test14_ugt(i32 %a) {
413 ; CHECK-LABEL: @test14_ugt(
414 ; CHECK: then:
415 ; CHECK-NEXT: %result = or i1 false, false
416   %a.off = add i32 %a, -8
417   %cmp = icmp ugt i32 %a.off, 8
418   br i1 %cmp, label %then, label %else
420 then:
421   %dead.1 = icmp eq i32 %a, 8
422   %dead.2 = icmp eq i32 %a, 16
423   %result = or i1 %dead.1, %dead.2
424   ret i1 %result
426 else:
427   ret i1 false
430 define i1 @test14_uge(i32 %a) {
431 ; CHECK-LABEL: @test14_uge(
432 ; CHECK: then:
433 ; CHECK-NEXT: %alive = icmp eq i32 %a, 16
434 ; CHECK-NEXT: %result = or i1 false, %alive
435   %a.off = add i32 %a, -8
436   %cmp = icmp uge i32 %a.off, 8
437   br i1 %cmp, label %then, label %else
439 then:
440   %dead = icmp eq i32 %a, 8
441   %alive = icmp eq i32 %a, 16
442   %result = or i1 %dead, %alive
443   ret i1 %result
445 else:
446   ret i1 false
449 @limit = external global i32
450 define i1 @test15(i32 %a) {
451 ; CHECK-LABEL: @test15(
452 ; CHECK: then:
453 ; CHECK-NEXT: ret i1 false
454   %limit = load i32, i32* @limit, !range !{i32 0, i32 256}
455   %cmp = icmp ult i32 %a, %limit
456   br i1 %cmp, label %then, label %else
458 then:
459   %result = icmp eq i32 %a, 255
460   ret i1 %result
462 else:
463   ret i1 false
466 define i32 @test16(i8 %a) {
467 entry:
468   %b = zext i8 %a to i32
469   br label %dispatch
471 dispatch:
472   %cmp = icmp eq i8 %a, 93
473   br i1 %cmp, label %target93, label %dispatch
475 ; CHECK-LABEL: @test16(
476 ; CHECK: target93:
477 ; CHECK-NEXT: ret i32 93
478 target93:
479   ret i32 %b
482 define i32 @test16_i1(i1 %a) {
483 entry:
484   %b = zext i1 %a to i32
485   br label %dispatch
487 dispatch:
488   br i1 %a, label %true, label %dispatch
490 ; CHECK-LABEL: @test16_i1(
491 ; CHECK: true:
492 ; CHECK-NEXT: ret i32 1
493 true:
494   ret i32 %b
497 define i8 @test17(i8 %a) {
498 entry:
499   %c = add i8 %a, 3
500   br label %dispatch
502 dispatch:
503   %cmp = icmp eq i8 %a, 93
504   br i1 %cmp, label %target93, label %dispatch
506 ; CHECK-LABEL: @test17(
507 ; CHECK: target93:
508 ; CHECK-NEXT: ret i8 96
509 target93:
510   ret i8 %c
513 define i8 @test17_2(i8 %a) {
514 entry:
515   %c = add i8 %a, %a
516   br label %dispatch
518 dispatch:
519   %cmp = icmp eq i8 %a, 93
520   br i1 %cmp, label %target93, label %dispatch
522 ; CHECK-LABEL: @test17_2(
523 ; CHECK: target93:
524 ; CHECK-NEXT: ret i8 -70
525 target93:
526   ret i8 %c
529 define i1 @test17_i1(i1 %a) {
530 entry:
531   %c = and i1 %a, true
532   br label %dispatch
534 dispatch:
535   br i1 %a, label %true, label %dispatch
537 ; CHECK-LABEL: @test17_i1(
538 ; CHECK: true:
539 ; CHECK-NEXT: ret i1 true
540 true:
541   ret i1 %c
544 define i32 @test18(i8 %a) {
545 entry:
546   %b = zext i8 %a to i32
547   br label %dispatch
549 dispatch:
550   switch i8 %a, label %dispatch [
551     i8 93, label %target93
552     i8 -111, label %dispatch
553   ]
555 ; CHECK-LABEL: @test18(
556 ; CHECK: target93:
557 ; CHECK-NEXT: ret i32 93
558 target93:
559   ret i32 %b
562 define i8 @test19(i8 %a) {
563 entry:
564   %c = add i8 %a, 3
565   br label %dispatch
567 dispatch:
568   switch i8 %a, label %dispatch [
569     i8 93, label %target93
570     i8 -111, label %dispatch
571   ]
573 ; CHECK-LABEL: @test19(
574 ; CHECK: target93:
575 ; CHECK-NEXT: ret i8 96
576 target93:
577   ret i8 %c
580 define i1 @test20(i64 %a) {
581 entry:
582   %b = and i64 %a, 7
583   br label %dispatch
585 dispatch:
586   switch i64 %a, label %default [
587     i64 0, label %exit2
588     i64 -2147483647, label %exit2
589   ]
591 default:
592   %c = icmp eq i64 %b, 0
593   br label %exit
595 exit:
596 ; Negative test. Shouldn't be incorrectly optimized to "ret i1 false".
597 ; CHECK-LABEL: @test20(
598 ; CHECK: exit:
599 ; CHECK-NOT: ret i1 false
600 ; CHECK: exit2:
601   ret i1 %c
603 exit2:
604   ret i1 false