1 ; RUN: opt -correlated-propagation -S < %s | FileCheck %s
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
11 %dead = icmp eq i32 %a, 7
12 br i1 %dead, label %end, label %else
20 ; CHECK-LABEL: @test1(
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
31 %dead = icmp ugt i32 %a, 15
32 br i1 %dead, label %end, label %else
40 ; CHECK-LABEL: @test2(
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
54 %cmp1 = icmp slt i32 %c, 3
55 br i1 %cmp1, label %if.then2, label %if.end8
59 %cmp2 = icmp eq i32 %c, 2
61 br i1 %cmp2, label %if.then4, label %if.end6
74 ; CHECK-LABEL: @test4(
75 define i32 @test4(i32 %c) nounwind {
76 switch i32 %c, label %sw.default [
84 %cmp = icmp sge i32 %c, 1
86 br i1 %cmp, label %if.then, label %if.end
98 %retval.0 = phi i32 [ 42, %sw.default ], [ 4, %if.then ], [ 9, %if.end ]
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
108 %cmp1 = icmp eq i32 %c, 4
109 br i1 %cmp1, label %if.end, label %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
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
130 ; CHECK: icmp eq i32 %c, 6
132 switch i32 %c, label %if.end [
141 %cmp2 = icmp eq i32 %c, 6
146 ; CHECK-LABEL: @test7(
147 define i1 @test7(i32 %c) nounwind {
149 switch i32 %c, label %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
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
177 define i1 @test9(i64* %p) {
178 ; CHECK-LABEL: @test9
180 %a = load i64, i64* %p, !range !{i64 0, i64 1}
181 %res = icmp eq i64 %a, 0
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
193 @g = external global i32
195 define i1 @test11() {
198 %positive = load i32, i32* @g, !range !{i32 1, i32 2048}
199 %add = add i32 %positive, 1
200 %test = icmp sgt i32 %add, 0
207 define i32 @test12(i32 %a, i32 %b) {
208 ; CHECK-LABEL: @test12(
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
215 %dead = icmp eq i32 %a, -1
216 br i1 %dead, label %end, label %else
225 define i32 @test12_swap(i32 %a, i32 %b) {
226 ; CHECK-LABEL: @test12_swap(
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
233 %dead = icmp eq i32 %a, -1
234 br i1 %dead, label %end, label %else
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(
247 ; CHECK-NEXT: %alive = icmp eq i32 %a, -1
248 %cmp = icmp ult i32 %a, %b
249 br i1 %cmp, label %then, label %else
252 %alive = icmp eq i32 %a, -1
253 br i1 %alive, label %end, label %then
262 define i32 @test12_signed(i32 %a, i32 %b) {
263 ; The same as @test12 but with signed comparison
264 ; CHECK-LABEL: @test12_signed(
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
271 %dead = icmp eq i32 %a, 2147483647
272 br i1 %dead, label %end, label %else
281 define i32 @test13(i32 %a, i32 %b) {
282 ; CHECK-LABEL: @test13(
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
290 %dead = icmp eq i32 %a, 7
291 br i1 %dead, label %end, label %else
300 define i32 @test13_swap(i32 %a, i32 %b) {
301 ; CHECK-LABEL: @test13_swap(
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
309 %dead = icmp eq i32 %a, 7
310 br i1 %dead, label %end, label %else
319 define i1 @test14_slt(i32 %a) {
320 ; CHECK-LABEL: @test14_slt(
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
328 %dead.1 = icmp eq i32 %a, -2147483641
329 %dead.2 = icmp eq i32 %a, 16
330 %result = or i1 %dead.1, %dead.2
337 define i1 @test14_sle(i32 %a) {
338 ; CHECK-LABEL: @test14_sle(
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
347 %dead = icmp eq i32 %a, -2147483641
348 %alive = icmp eq i32 %a, 16
349 %result = or i1 %dead, %alive
356 define i1 @test14_sgt(i32 %a) {
357 ; CHECK-LABEL: @test14_sgt(
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
365 %dead.1 = icmp eq i32 %a, -2147483640
366 %dead.2 = icmp eq i32 %a, 16
367 %result = or i1 %dead.1, %dead.2
374 define i1 @test14_sge(i32 %a) {
375 ; CHECK-LABEL: @test14_sge(
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
384 %dead = icmp eq i32 %a, -2147483640
385 %alive = icmp eq i32 %a, 16
386 %result = or i1 %dead, %alive
393 define i1 @test14_ule(i32 %a) {
394 ; CHECK-LABEL: @test14_ule(
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
403 %dead = icmp eq i32 %a, 7
404 %alive = icmp eq i32 %a, 16
405 %result = or i1 %dead, %alive
412 define i1 @test14_ugt(i32 %a) {
413 ; CHECK-LABEL: @test14_ugt(
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
421 %dead.1 = icmp eq i32 %a, 8
422 %dead.2 = icmp eq i32 %a, 16
423 %result = or i1 %dead.1, %dead.2
430 define i1 @test14_uge(i32 %a) {
431 ; CHECK-LABEL: @test14_uge(
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
440 %dead = icmp eq i32 %a, 8
441 %alive = icmp eq i32 %a, 16
442 %result = or i1 %dead, %alive
449 @limit = external global i32
450 define i1 @test15(i32 %a) {
451 ; CHECK-LABEL: @test15(
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
459 %result = icmp eq i32 %a, 255
466 define i32 @test16(i8 %a) {
468 %b = zext i8 %a to i32
472 %cmp = icmp eq i8 %a, 93
473 br i1 %cmp, label %target93, label %dispatch
475 ; CHECK-LABEL: @test16(
477 ; CHECK-NEXT: ret i32 93
482 define i32 @test16_i1(i1 %a) {
484 %b = zext i1 %a to i32
488 br i1 %a, label %true, label %dispatch
490 ; CHECK-LABEL: @test16_i1(
492 ; CHECK-NEXT: ret i32 1
497 define i8 @test17(i8 %a) {
503 %cmp = icmp eq i8 %a, 93
504 br i1 %cmp, label %target93, label %dispatch
506 ; CHECK-LABEL: @test17(
508 ; CHECK-NEXT: ret i8 96
513 define i8 @test17_2(i8 %a) {
519 %cmp = icmp eq i8 %a, 93
520 br i1 %cmp, label %target93, label %dispatch
522 ; CHECK-LABEL: @test17_2(
524 ; CHECK-NEXT: ret i8 -70
529 define i1 @test17_i1(i1 %a) {
535 br i1 %a, label %true, label %dispatch
537 ; CHECK-LABEL: @test17_i1(
539 ; CHECK-NEXT: ret i1 true
544 define i32 @test18(i8 %a) {
546 %b = zext i8 %a to i32
550 switch i8 %a, label %dispatch [
551 i8 93, label %target93
552 i8 -111, label %dispatch
555 ; CHECK-LABEL: @test18(
557 ; CHECK-NEXT: ret i32 93
562 define i8 @test19(i8 %a) {
568 switch i8 %a, label %dispatch [
569 i8 93, label %target93
570 i8 -111, label %dispatch
573 ; CHECK-LABEL: @test19(
575 ; CHECK-NEXT: ret i8 96
580 define i1 @test20(i64 %a) {
586 switch i64 %a, label %default [
588 i64 -2147483647, label %exit2
592 %c = icmp eq i64 %b, 0
596 ; Negative test. Shouldn't be incorrectly optimized to "ret i1 false".
597 ; CHECK-LABEL: @test20(
599 ; CHECK-NOT: ret i1 false