1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=correlated-propagation -S < %s | FileCheck %s
6 define i32 @test1(i32 %a) nounwind {
8 ; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
9 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A_OFF]], 8
10 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
12 ; CHECK-NEXT: br i1 false, label [[END:%.*]], label [[ELSE]]
14 ; CHECK-NEXT: ret i32 1
16 ; CHECK-NEXT: ret i32 2
18 %a.off = add i32 %a, -8
19 %cmp = icmp ult i32 %a.off, 8
20 br i1 %cmp, label %then, label %else
23 %dead = icmp eq i32 %a, 7
24 br i1 %dead, label %end, label %else
33 define i32 @test2(i32 %a) nounwind {
34 ; CHECK-LABEL: @test2(
35 ; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
36 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A_OFF]], 8
37 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
39 ; CHECK-NEXT: br i1 false, label [[END:%.*]], label [[ELSE]]
41 ; CHECK-NEXT: ret i32 1
43 ; CHECK-NEXT: ret i32 2
45 %a.off = add i32 %a, -8
46 %cmp = icmp ult i32 %a.off, 8
47 br i1 %cmp, label %then, label %else
50 %dead = icmp ugt i32 %a, 15
51 br i1 %dead, label %end, label %else
60 define i32 @test3(i32 %c) nounwind {
61 ; CHECK-LABEL: @test3(
62 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[C:%.*]], 2
63 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
65 ; CHECK-NEXT: ret i32 1
67 ; CHECK-NEXT: [[CMP1:%.*]] = icmp samesign ult i32 [[C]], 3
68 ; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END8:%.*]]
70 ; CHECK-NEXT: br i1 true, label [[IF_THEN4:%.*]], label [[IF_END6:%.*]]
72 ; CHECK-NEXT: ret i32 2
74 ; CHECK-NEXT: ret i32 3
76 ; CHECK-NEXT: ret i32 4
78 %cmp = icmp slt i32 %c, 2
79 br i1 %cmp, label %if.then, label %if.end
85 %cmp1 = icmp slt i32 %c, 3
86 br i1 %cmp1, label %if.then2, label %if.end8
89 %cmp2 = icmp eq i32 %c, 2
90 br i1 %cmp2, label %if.then4, label %if.end6
102 define i32 @test4(i32 %c) nounwind {
103 ; CHECK-LABEL: @test4(
104 ; CHECK-NEXT: switch i32 [[C:%.*]], label [[SW_DEFAULT:%.*]] [
105 ; CHECK-NEXT: i32 1, label [[SW_BB:%.*]]
106 ; CHECK-NEXT: i32 2, label [[SW_BB]]
107 ; CHECK-NEXT: i32 4, label [[SW_BB]]
110 ; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[IF_END:%.*]]
112 ; CHECK-NEXT: br label [[RETURN:%.*]]
114 ; CHECK-NEXT: br label [[RETURN]]
116 ; CHECK-NEXT: br label [[RETURN]]
118 ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 42, [[SW_DEFAULT]] ], [ 4, [[IF_THEN]] ], [ 9, [[IF_END]] ]
119 ; CHECK-NEXT: ret i32 [[RETVAL_0]]
121 switch i32 %c, label %sw.default [
128 %cmp = icmp sge i32 %c, 1
129 br i1 %cmp, label %if.then, label %if.end
141 %retval.0 = phi i32 [ 42, %sw.default ], [ 4, %if.then ], [ 9, %if.end ]
145 define i1 @test5(i32 %c) nounwind {
146 ; CHECK-LABEL: @test5(
147 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[C:%.*]], 5
148 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
150 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[C]], 4
151 ; CHECK-NEXT: br i1 [[CMP1]], label [[IF_END]], label [[IF_END8:%.*]]
153 ; CHECK-NEXT: ret i1 true
155 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[C]], 3
156 ; CHECK-NEXT: [[OR:%.*]] = or i1 false, false
157 ; CHECK-NEXT: ret i1 [[CMP2]]
159 %cmp = icmp slt i32 %c, 5
160 br i1 %cmp, label %if.then, label %if.end
163 %cmp1 = icmp eq i32 %c, 4
164 br i1 %cmp1, label %if.end, label %if.end8
170 %cmp2 = icmp eq i32 %c, 3
171 %cmp3 = icmp eq i32 %c, 4
172 %cmp4 = icmp eq i32 %c, 6
173 %or = or i1 %cmp3, %cmp4
177 define i1 @test6(i32 %c) nounwind {
178 ; CHECK-LABEL: @test6(
179 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[C:%.*]], 7
180 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
182 ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[C]], 6
183 ; CHECK-NEXT: br i1 [[COND]], label [[SW_BB:%.*]], label [[IF_END]]
185 ; CHECK-NEXT: ret i1 true
187 ; CHECK-NEXT: ret i1 true
189 %cmp = icmp ule i32 %c, 7
190 br i1 %cmp, label %if.then, label %if.end
193 switch i32 %c, label %if.end [
202 %cmp2 = icmp eq i32 %c, 6
206 define i1 @test7(i32 %c) nounwind {
207 ; CHECK-LABEL: @test7(
209 ; CHECK-NEXT: switch i32 [[C:%.*]], label [[SW_DEFAULT:%.*]] [
210 ; CHECK-NEXT: i32 6, label [[SW_BB:%.*]]
211 ; CHECK-NEXT: i32 7, label [[SW_BB]]
214 ; CHECK-NEXT: ret i1 true
216 ; CHECK-NEXT: [[CMP5:%.*]] = icmp eq i32 [[C]], 5
217 ; CHECK-NEXT: [[CMP8:%.*]] = icmp eq i32 [[C]], 8
218 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP5]], false
219 ; CHECK-NEXT: [[OR2:%.*]] = or i1 false, [[CMP8]]
220 ; CHECK-NEXT: ret i1 false
223 switch i32 %c, label %sw.default [
232 %cmp5 = icmp eq i32 %c, 5
233 %cmp6 = icmp eq i32 %c, 6
234 %cmp7 = icmp eq i32 %c, 7
235 %cmp8 = icmp eq i32 %c, 8
236 %or = or i1 %cmp5, %cmp6
237 %or2 = or i1 %cmp7, %cmp8
241 define i1 @test8(ptr %p) {
242 ; CHECK-LABEL: @test8(
243 ; CHECK-NEXT: [[A:%.*]] = load i64, ptr [[P:%.*]], align 4, !range [[RNG0:![0-9]+]]
244 ; CHECK-NEXT: ret i1 false
246 %a = load i64, ptr %p, !range !{i64 4, i64 255}
247 %res = icmp eq i64 %a, 0
251 define i1 @test9(ptr %p) {
252 ; CHECK-LABEL: @test9(
253 ; CHECK-NEXT: [[A:%.*]] = load i64, ptr [[P:%.*]], align 4, !range [[RNG1:![0-9]+]]
254 ; CHECK-NEXT: ret i1 true
256 %a = load i64, ptr %p, !range !{i64 0, i64 1}
257 %res = icmp eq i64 %a, 0
261 define i1 @test10(ptr %p) {
262 ; CHECK-LABEL: @test10(
263 ; CHECK-NEXT: [[A:%.*]] = load i64, ptr [[P:%.*]], align 4, !range [[RNG2:![0-9]+]]
264 ; CHECK-NEXT: ret i1 false
266 %a = load i64, ptr %p, !range !{i64 4, i64 8, i64 15, i64 20}
267 %res = icmp eq i64 %a, 0
271 @g = external global i32
273 define i1 @test11() {
274 ; CHECK-LABEL: @test11(
275 ; CHECK-NEXT: [[POSITIVE:%.*]] = load i32, ptr @g, align 4, !range [[RNG3:![0-9]+]]
276 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[POSITIVE]], 1
277 ; CHECK-NEXT: br label [[NEXT:%.*]]
279 ; CHECK-NEXT: ret i1 true
281 %positive = load i32, ptr @g, !range !{i32 1, i32 2048}
282 %add = add i32 %positive, 1
283 %test = icmp sgt i32 %add, 0
290 define i32 @test12(i32 %a, i32 %b) {
291 ; CHECK-LABEL: @test12(
292 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
293 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
295 ; CHECK-NEXT: br i1 false, label [[END:%.*]], label [[ELSE]]
297 ; CHECK-NEXT: ret i32 1
299 ; CHECK-NEXT: ret i32 2
301 %cmp = icmp ult i32 %a, %b
302 br i1 %cmp, label %then, label %else
305 %dead = icmp eq i32 %a, -1
306 br i1 %dead, label %end, label %else
315 define i32 @test12_swap(i32 %a, i32 %b) {
316 ; CHECK-LABEL: @test12_swap(
317 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[B:%.*]], [[A:%.*]]
318 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
320 ; CHECK-NEXT: br i1 false, label [[END:%.*]], label [[ELSE]]
322 ; CHECK-NEXT: ret i32 1
324 ; CHECK-NEXT: ret i32 2
326 %cmp = icmp ugt i32 %b, %a
327 br i1 %cmp, label %then, label %else
330 %dead = icmp eq i32 %a, -1
331 br i1 %dead, label %end, label %else
340 ; The same as @test12 but the second check is on the false path
342 define i32 @test12_neg(i32 %a, i32 %b) {
343 ; CHECK-LABEL: @test12_neg(
344 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]
345 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
347 ; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], -1
348 ; CHECK-NEXT: br i1 [[ALIVE]], label [[END:%.*]], label [[THEN]]
350 ; CHECK-NEXT: ret i32 1
352 ; CHECK-NEXT: ret i32 2
354 %cmp = icmp ult i32 %a, %b
355 br i1 %cmp, label %then, label %else
358 %alive = icmp eq i32 %a, -1
359 br i1 %alive, label %end, label %then
368 ; The same as @test12 but with signed comparison
370 define i32 @test12_signed(i32 %a, i32 %b) {
371 ; CHECK-LABEL: @test12_signed(
372 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]
373 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
375 ; CHECK-NEXT: br i1 false, label [[END:%.*]], label [[ELSE]]
377 ; CHECK-NEXT: ret i32 1
379 ; CHECK-NEXT: ret i32 2
381 %cmp = icmp slt i32 %a, %b
382 br i1 %cmp, label %then, label %else
385 %dead = icmp eq i32 %a, 2147483647
386 br i1 %dead, label %end, label %else
395 define i32 @test13(i32 %a, i32 %b) {
396 ; CHECK-LABEL: @test13(
397 ; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
398 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A_OFF]], [[B:%.*]]
399 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
401 ; CHECK-NEXT: br i1 false, label [[END:%.*]], label [[ELSE]]
403 ; CHECK-NEXT: ret i32 1
405 ; CHECK-NEXT: ret i32 2
407 %a.off = add i32 %a, -8
408 %cmp = icmp ult i32 %a.off, %b
409 br i1 %cmp, label %then, label %else
412 %dead = icmp eq i32 %a, 7
413 br i1 %dead, label %end, label %else
422 define i32 @test13_swap(i32 %a, i32 %b) {
423 ; CHECK-LABEL: @test13_swap(
424 ; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
425 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[B:%.*]], [[A_OFF]]
426 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
428 ; CHECK-NEXT: br i1 false, label [[END:%.*]], label [[ELSE]]
430 ; CHECK-NEXT: ret i32 1
432 ; CHECK-NEXT: ret i32 2
434 %a.off = add i32 %a, -8
435 %cmp = icmp ugt i32 %b, %a.off
436 br i1 %cmp, label %then, label %else
439 %dead = icmp eq i32 %a, 7
440 br i1 %dead, label %end, label %else
449 define i1 @test14_slt(i32 %a) {
450 ; CHECK-LABEL: @test14_slt(
451 ; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
452 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A_OFF]], 8
453 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
455 ; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, false
456 ; CHECK-NEXT: ret i1 false
458 ; CHECK-NEXT: ret i1 false
460 %a.off = add i32 %a, -8
461 %cmp = icmp slt i32 %a.off, 8
462 br i1 %cmp, label %then, label %else
465 %dead.1 = icmp eq i32 %a, -2147483641
466 %dead.2 = icmp eq i32 %a, 16
467 %result = or i1 %dead.1, %dead.2
474 define i1 @test14_sle(i32 %a) {
475 ; CHECK-LABEL: @test14_sle(
476 ; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
477 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A_OFF]], 8
478 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
480 ; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], 16
481 ; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, [[ALIVE]]
482 ; CHECK-NEXT: ret i1 [[RESULT]]
484 ; CHECK-NEXT: ret i1 false
486 %a.off = add i32 %a, -8
487 %cmp = icmp sle i32 %a.off, 8
488 br i1 %cmp, label %then, label %else
491 %dead = icmp eq i32 %a, -2147483641
492 %alive = icmp eq i32 %a, 16
493 %result = or i1 %dead, %alive
500 define i1 @test14_sgt(i32 %a) {
501 ; CHECK-LABEL: @test14_sgt(
502 ; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
503 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A_OFF]], 8
504 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
506 ; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, false
507 ; CHECK-NEXT: ret i1 false
509 ; CHECK-NEXT: ret i1 false
511 %a.off = add i32 %a, -8
512 %cmp = icmp sgt i32 %a.off, 8
513 br i1 %cmp, label %then, label %else
516 %dead.1 = icmp eq i32 %a, -2147483640
517 %dead.2 = icmp eq i32 %a, 16
518 %result = or i1 %dead.1, %dead.2
525 define i1 @test14_sge(i32 %a) {
526 ; CHECK-LABEL: @test14_sge(
527 ; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
528 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A_OFF]], 8
529 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
531 ; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], 16
532 ; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, [[ALIVE]]
533 ; CHECK-NEXT: ret i1 [[RESULT]]
535 ; CHECK-NEXT: ret i1 false
537 %a.off = add i32 %a, -8
538 %cmp = icmp sge i32 %a.off, 8
539 br i1 %cmp, label %then, label %else
542 %dead = icmp eq i32 %a, -2147483640
543 %alive = icmp eq i32 %a, 16
544 %result = or i1 %dead, %alive
551 define i1 @test14_ule(i32 %a) {
552 ; CHECK-LABEL: @test14_ule(
553 ; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
554 ; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[A_OFF]], 8
555 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
557 ; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], 16
558 ; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, [[ALIVE]]
559 ; CHECK-NEXT: ret i1 [[RESULT]]
561 ; CHECK-NEXT: ret i1 false
563 %a.off = add i32 %a, -8
564 %cmp = icmp ule i32 %a.off, 8
565 br i1 %cmp, label %then, label %else
568 %dead = icmp eq i32 %a, 7
569 %alive = icmp eq i32 %a, 16
570 %result = or i1 %dead, %alive
577 define i1 @test14_ugt(i32 %a) {
578 ; CHECK-LABEL: @test14_ugt(
579 ; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
580 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A_OFF]], 8
581 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
583 ; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, false
584 ; CHECK-NEXT: ret i1 false
586 ; CHECK-NEXT: ret i1 false
588 %a.off = add i32 %a, -8
589 %cmp = icmp ugt i32 %a.off, 8
590 br i1 %cmp, label %then, label %else
593 %dead.1 = icmp eq i32 %a, 8
594 %dead.2 = icmp eq i32 %a, 16
595 %result = or i1 %dead.1, %dead.2
602 define i1 @test14_uge(i32 %a) {
603 ; CHECK-LABEL: @test14_uge(
604 ; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
605 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A_OFF]], 8
606 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
608 ; CHECK-NEXT: [[ALIVE:%.*]] = icmp eq i32 [[A]], 16
609 ; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, [[ALIVE]]
610 ; CHECK-NEXT: ret i1 [[RESULT]]
612 ; CHECK-NEXT: ret i1 false
614 %a.off = add i32 %a, -8
615 %cmp = icmp uge i32 %a.off, 8
616 br i1 %cmp, label %then, label %else
619 %dead = icmp eq i32 %a, 8
620 %alive = icmp eq i32 %a, 16
621 %result = or i1 %dead, %alive
628 define i1 @test14_ugt_and(i32 %a) {
629 ; CHECK-LABEL: @test14_ugt_and(
630 ; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
631 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A_OFF]], 8
632 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
634 ; CHECK-NEXT: [[RESULT:%.*]] = and i1 false, false
635 ; CHECK-NEXT: ret i1 false
637 ; CHECK-NEXT: ret i1 false
639 %a.off = add i32 %a, -8
640 %cmp = icmp ugt i32 %a.off, 8
641 br i1 %cmp, label %then, label %else
644 %dead.1 = icmp eq i32 %a, 8
645 %dead.2 = icmp eq i32 %a, 16
646 %result = and i1 %dead.1, %dead.2
653 @limit = external global i32
654 define i1 @test15(i32 %a) {
655 ; CHECK-LABEL: @test15(
656 ; CHECK-NEXT: [[LIMIT:%.*]] = load i32, ptr @limit, align 4, !range [[RNG4:![0-9]+]]
657 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[LIMIT]]
658 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
660 ; CHECK-NEXT: ret i1 false
662 ; CHECK-NEXT: ret i1 false
664 %limit = load i32, ptr @limit, !range !{i32 0, i32 256}
665 %cmp = icmp ult i32 %a, %limit
666 br i1 %cmp, label %then, label %else
669 %result = icmp eq i32 %a, 255
676 define i32 @test16(i8 %a) {
677 ; CHECK-LABEL: @test16(
679 ; CHECK-NEXT: [[B:%.*]] = zext i8 [[A:%.*]] to i32
680 ; CHECK-NEXT: br label [[DISPATCH:%.*]]
682 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 93
683 ; CHECK-NEXT: br i1 [[CMP]], label [[TARGET93:%.*]], label [[DISPATCH]]
685 ; CHECK-NEXT: ret i32 93
688 %b = zext i8 %a to i32
692 %cmp = icmp eq i8 %a, 93
693 br i1 %cmp, label %target93, label %dispatch
699 define i32 @test16_i1(i1 %a) {
700 ; CHECK-LABEL: @test16_i1(
702 ; CHECK-NEXT: [[B:%.*]] = zext i1 [[A:%.*]] to i32
703 ; CHECK-NEXT: br label [[DISPATCH:%.*]]
705 ; CHECK-NEXT: br i1 [[A]], label [[TRUE:%.*]], label [[DISPATCH]]
707 ; CHECK-NEXT: ret i32 1
710 %b = zext i1 %a to i32
714 br i1 %a, label %true, label %dispatch
720 define i8 @test17(i8 %a) {
721 ; CHECK-LABEL: @test17(
723 ; CHECK-NEXT: [[C:%.*]] = add i8 [[A:%.*]], 3
724 ; CHECK-NEXT: br label [[DISPATCH:%.*]]
726 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 93
727 ; CHECK-NEXT: br i1 [[CMP]], label [[TARGET93:%.*]], label [[DISPATCH]]
729 ; CHECK-NEXT: ret i8 96
736 %cmp = icmp eq i8 %a, 93
737 br i1 %cmp, label %target93, label %dispatch
743 define i8 @test17_2(i8 %a) {
744 ; CHECK-LABEL: @test17_2(
746 ; CHECK-NEXT: [[C:%.*]] = add i8 [[A:%.*]], [[A]]
747 ; CHECK-NEXT: br label [[DISPATCH:%.*]]
749 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], 93
750 ; CHECK-NEXT: br i1 [[CMP]], label [[TARGET93:%.*]], label [[DISPATCH]]
752 ; CHECK-NEXT: ret i8 -70
759 %cmp = icmp eq i8 %a, 93
760 br i1 %cmp, label %target93, label %dispatch
766 define i1 @test17_i1(i1 %a) {
767 ; CHECK-LABEL: @test17_i1(
769 ; CHECK-NEXT: br label [[DISPATCH:%.*]]
771 ; CHECK-NEXT: br i1 [[A:%.*]], label [[TRUE:%.*]], label [[DISPATCH]]
773 ; CHECK-NEXT: ret i1 true
780 br i1 %a, label %true, label %dispatch
786 define i32 @test18(i8 %a) {
787 ; CHECK-LABEL: @test18(
789 ; CHECK-NEXT: [[B:%.*]] = zext i8 [[A:%.*]] to i32
790 ; CHECK-NEXT: br label [[DISPATCH:%.*]]
792 ; CHECK-NEXT: switch i8 [[A]], label [[DISPATCH]] [
793 ; CHECK-NEXT: i8 93, label [[TARGET93:%.*]]
794 ; CHECK-NEXT: i8 -111, label [[DISPATCH]]
797 ; CHECK-NEXT: ret i32 93
800 %b = zext i8 %a to i32
804 switch i8 %a, label %dispatch [
805 i8 93, label %target93
806 i8 -111, label %dispatch
813 define i8 @test19(i8 %a) {
814 ; CHECK-LABEL: @test19(
816 ; CHECK-NEXT: [[C:%.*]] = add i8 [[A:%.*]], 3
817 ; CHECK-NEXT: br label [[DISPATCH:%.*]]
819 ; CHECK-NEXT: switch i8 [[A]], label [[DISPATCH]] [
820 ; CHECK-NEXT: i8 93, label [[TARGET93:%.*]]
821 ; CHECK-NEXT: i8 -111, label [[DISPATCH]]
824 ; CHECK-NEXT: ret i8 96
831 switch i8 %a, label %dispatch [
832 i8 93, label %target93
833 i8 -111, label %dispatch
840 ; Negative test. Shouldn't be incorrectly optimized to "ret i1 false".
842 define i1 @test20(i64 %a) {
843 ; CHECK-LABEL: @test20(
845 ; CHECK-NEXT: [[B:%.*]] = and i64 [[A:%.*]], 7
846 ; CHECK-NEXT: br label [[DISPATCH:%.*]]
848 ; CHECK-NEXT: switch i64 [[A]], label [[DEFAULT:%.*]] [
849 ; CHECK-NEXT: i64 0, label [[EXIT2:%.*]]
850 ; CHECK-NEXT: i64 -2147483647, label [[EXIT2]]
853 ; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[B]], 0
854 ; CHECK-NEXT: br label [[EXIT:%.*]]
856 ; CHECK-NEXT: ret i1 [[C]]
858 ; CHECK-NEXT: ret i1 false
865 switch i64 %a, label %default [
867 i64 -2147483647, label %exit2
871 %c = icmp eq i64 %b, 0
881 define i1 @slt(i8 %a, i8 %b) {
884 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A:%.*]], [[B:%.*]]
885 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
886 ; CHECK-NEXT: ret i1 true
889 %cmp = icmp slt i8 %a, %b
890 call void @llvm.assume(i1 %cmp)
891 %res = icmp slt i8 %a, 127
895 define i1 @sgt(i8 %a, i8 %b) {
898 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], [[B:%.*]]
899 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
900 ; CHECK-NEXT: ret i1 true
903 %cmp = icmp sgt i8 %a, %b
904 call void @llvm.assume(i1 %cmp)
905 %res = icmp sgt i8 %a, -128
909 define i1 @ult(i8 %a, i8 %b) {
912 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A:%.*]], [[B:%.*]]
913 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
914 ; CHECK-NEXT: ret i1 true
917 %cmp = icmp ult i8 %a, %b
918 call void @llvm.assume(i1 %cmp)
919 %res = icmp ult i8 %a, 255
923 define i1 @ugt(i8 %a, i8 %b) {
926 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]]
927 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
928 ; CHECK-NEXT: ret i1 true
931 %cmp = icmp ugt i8 %a, %b
932 call void @llvm.assume(i1 %cmp)
933 %res = icmp ugt i8 %a, 0
937 define i1 @ctlz_with_range_metadata(i16 %x) {
938 ; CHECK-LABEL: @ctlz_with_range_metadata(
939 ; CHECK-NEXT: [[CTLZ:%.*]] = call i16 @llvm.ctlz.i16(i16 [[X:%.*]], i1 false), !range [[RNG5:![0-9]+]]
940 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[CTLZ]] to i8
941 ; CHECK-NEXT: ret i1 true
943 %ctlz = call i16 @llvm.ctlz.i16(i16 %x, i1 false), !range !{i16 0, i16 8}
944 %trunc = trunc i16 %ctlz to i8
945 %res = icmp ult i8 %trunc, 8
949 define i1 @abs_with_range_metadata(i16 %x) {
950 ; CHECK-LABEL: @abs_with_range_metadata(
951 ; CHECK-NEXT: [[ABS:%.*]] = call i16 @llvm.abs.i16(i16 [[X:%.*]], i1 false), !range [[RNG5]]
952 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[ABS]] to i8
953 ; CHECK-NEXT: ret i1 true
955 %abs = call i16 @llvm.abs.i16(i16 %x, i1 false), !range !{i16 0, i16 8}
956 %trunc = trunc i16 %abs to i8
957 %res = icmp ult i8 %trunc, 8
961 define i1 @ctlz_fold(i16 %x) {
962 ; CHECK-LABEL: @ctlz_fold(
963 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X:%.*]], 256
964 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[ELSE:%.*]]
966 ; CHECK-NEXT: [[CTLZ:%.*]] = call i16 @llvm.ctlz.i16(i16 [[X]], i1 false)
967 ; CHECK-NEXT: ret i1 true
969 ; CHECK-NEXT: [[CTLZ2:%.*]] = call i16 @llvm.ctlz.i16(i16 [[X]], i1 false)
970 ; CHECK-NEXT: ret i1 true
972 %cmp = icmp ult i16 %x, 256
973 br i1 %cmp, label %if, label %else
976 %ctlz = call i16 @llvm.ctlz.i16(i16 %x, i1 false)
977 %res = icmp uge i16 %ctlz, 8
981 %ctlz2 = call i16 @llvm.ctlz.i16(i16 %x, i1 false)
982 %res2 = icmp ult i16 %ctlz2, 8
986 define i1 @ctlz_nofold(i16 %x) {
987 ; CHECK-LABEL: @ctlz_nofold(
988 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X:%.*]], 256
989 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[ELSE:%.*]]
991 ; CHECK-NEXT: [[CTLZ:%.*]] = call i16 @llvm.ctlz.i16(i16 [[X]], i1 false)
992 ; CHECK-NEXT: [[RES:%.*]] = icmp samesign uge i16 [[CTLZ]], 9
993 ; CHECK-NEXT: ret i1 [[RES]]
995 ; CHECK-NEXT: [[CTLZ2:%.*]] = call i16 @llvm.ctlz.i16(i16 [[X]], i1 false)
996 ; CHECK-NEXT: [[RES2:%.*]] = icmp samesign ult i16 [[CTLZ2]], 7
997 ; CHECK-NEXT: ret i1 [[RES2]]
999 %cmp = icmp ult i16 %x, 256
1000 br i1 %cmp, label %if, label %else
1003 %ctlz = call i16 @llvm.ctlz.i16(i16 %x, i1 false)
1004 %res = icmp uge i16 %ctlz, 9
1008 %ctlz2 = call i16 @llvm.ctlz.i16(i16 %x, i1 false)
1009 %res2 = icmp ult i16 %ctlz2, 7
1013 define i1 @cttz_fold(i16 %x) {
1014 ; CHECK-LABEL: @cttz_fold(
1015 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X:%.*]], 256
1016 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[ELSE:%.*]]
1018 ; CHECK-NEXT: [[CTTZ:%.*]] = call i16 @llvm.cttz.i16(i16 [[X]], i1 true)
1019 ; CHECK-NEXT: ret i1 false
1021 ; CHECK-NEXT: ret i1 false
1023 %cmp = icmp ult i16 %x, 256
1024 br i1 %cmp, label %if, label %else
1027 %cttz = call i16 @llvm.cttz.i16(i16 %x, i1 true)
1028 %res = icmp uge i16 %cttz, 8
1035 define i1 @cttz_nofold1(i16 %x) {
1036 ; CHECK-LABEL: @cttz_nofold1(
1037 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X:%.*]], 256
1038 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[ELSE:%.*]]
1040 ; CHECK-NEXT: [[CTTZ:%.*]] = call i16 @llvm.cttz.i16(i16 [[X]], i1 true)
1041 ; CHECK-NEXT: [[RES:%.*]] = icmp samesign uge i16 [[CTTZ]], 7
1042 ; CHECK-NEXT: ret i1 [[RES]]
1044 ; CHECK-NEXT: ret i1 false
1046 %cmp = icmp ult i16 %x, 256
1047 br i1 %cmp, label %if, label %else
1050 %cttz = call i16 @llvm.cttz.i16(i16 %x, i1 true)
1051 %res = icmp uge i16 %cttz, 7
1058 define i1 @cttz_nofold2(i16 %x) {
1059 ; CHECK-LABEL: @cttz_nofold2(
1060 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X:%.*]], 256
1061 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[ELSE:%.*]]
1063 ; CHECK-NEXT: [[CTTZ:%.*]] = call i16 @llvm.cttz.i16(i16 [[X]], i1 false)
1064 ; CHECK-NEXT: [[RES:%.*]] = icmp samesign uge i16 [[CTTZ]], 8
1065 ; CHECK-NEXT: ret i1 [[RES]]
1067 ; CHECK-NEXT: ret i1 false
1069 %cmp = icmp ult i16 %x, 256
1070 br i1 %cmp, label %if, label %else
1073 %cttz = call i16 @llvm.cttz.i16(i16 %x, i1 false)
1074 %res = icmp uge i16 %cttz, 8
1081 define i1 @ctpop_fold(i16 %x) {
1082 ; CHECK-LABEL: @ctpop_fold(
1083 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X:%.*]], 256
1084 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[ELSE:%.*]]
1086 ; CHECK-NEXT: [[CTPOP:%.*]] = call i16 @llvm.ctpop.i16(i16 [[X]])
1087 ; CHECK-NEXT: ret i1 true
1089 ; CHECK-NEXT: ret i1 true
1091 %cmp = icmp ult i16 %x, 256
1092 br i1 %cmp, label %if, label %else
1095 %ctpop = call i16 @llvm.ctpop.i16(i16 %x)
1096 %res = icmp ule i16 %ctpop, 8
1103 define i1 @ctpop_nofold(i16 %x) {
1104 ; CHECK-LABEL: @ctpop_nofold(
1105 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[X:%.*]], 256
1106 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[ELSE:%.*]]
1108 ; CHECK-NEXT: [[CTPOP:%.*]] = call i16 @llvm.ctpop.i16(i16 [[X]])
1109 ; CHECK-NEXT: [[RES:%.*]] = icmp samesign ule i16 [[CTPOP]], 7
1110 ; CHECK-NEXT: ret i1 [[RES]]
1112 ; CHECK-NEXT: ret i1 true
1114 %cmp = icmp ult i16 %x, 256
1115 br i1 %cmp, label %if, label %else
1118 %ctpop = call i16 @llvm.ctpop.i16(i16 %x)
1119 %res = icmp ule i16 %ctpop, 7
1126 define i1 @icmp_eq_range_attr(i8 range(i8 1, 0) %i) {
1127 ; CHECK-LABEL: @icmp_eq_range_attr(
1128 ; CHECK-NEXT: ret i1 false
1130 %cmp = icmp eq i8 %i, 0
1134 define i1 @neg_icmp_eq_range_attr(i8 range(i8 -1, 1) %i) {
1135 ; CHECK-LABEL: @neg_icmp_eq_range_attr(
1136 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I:%.*]], 0
1137 ; CHECK-NEXT: ret i1 [[CMP]]
1139 %cmp = icmp eq i8 %i, 0
1143 declare range(i8 1, 0) i8 @returns_non_zero_range_helper()
1144 declare range(i8 -1, 1) i8 @returns_contain_zero_range_helper()
1146 define i1 @icmp_eq_range_return() {
1147 ; CHECK-LABEL: @icmp_eq_range_return(
1148 ; CHECK-NEXT: [[I:%.*]] = call i8 @returns_non_zero_range_helper()
1149 ; CHECK-NEXT: ret i1 false
1151 %i = call i8 @returns_non_zero_range_helper()
1152 %cmp = icmp eq i8 %i, 0
1156 define i1 @neg_icmp_eq_range_return() {
1157 ; CHECK-LABEL: @neg_icmp_eq_range_return(
1158 ; CHECK-NEXT: [[I:%.*]] = call i8 @returns_contain_zero_range_helper()
1159 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 0
1160 ; CHECK-NEXT: ret i1 [[CMP]]
1162 %i = call i8 @returns_contain_zero_range_helper()
1163 %cmp = icmp eq i8 %i, 0
1167 declare i8 @returns_i8_helper()
1169 define i1 @icmp_eq_range_call() {
1170 ; CHECK-LABEL: @icmp_eq_range_call(
1171 ; CHECK-NEXT: [[I:%.*]] = call range(i8 1, 0) i8 @returns_i8_helper()
1172 ; CHECK-NEXT: ret i1 false
1174 %i = call range(i8 1, 0) i8 @returns_i8_helper()
1175 %cmp = icmp eq i8 %i, 0
1179 define i1 @neg_icmp_eq_range_call() {
1180 ; CHECK-LABEL: @neg_icmp_eq_range_call(
1181 ; CHECK-NEXT: [[I:%.*]] = call range(i8 0, 11) i8 @returns_i8_helper()
1182 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 0
1183 ; CHECK-NEXT: ret i1 [[CMP]]
1185 %i = call range(i8 0, 11) i8 @returns_i8_helper()
1186 %cmp = icmp eq i8 %i, 0
1190 declare i16 @llvm.ctlz.i16(i16, i1)
1191 declare i16 @llvm.cttz.i16(i16, i1)
1192 declare i16 @llvm.ctpop.i16(i16)
1193 declare i16 @llvm.abs.i16(i16, i1)
1194 declare void @llvm.assume(i1)