1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
5 define i32 @test1(i1 %C) {
7 ; CHECK-NEXT: br i1 [[C:%.*]], label [[EXIT:%.*]], label [[BODY:%.*]]
9 ; CHECK-NEXT: ret i32 11
11 ; CHECK-NEXT: ret i32 10
13 br i1 %C, label %exit, label %body
16 %A = select i1 %C, i32 10, i32 11
26 ; CHECK-LABEL: @test2(
28 ; CHECK-NEXT: [[COND:%.*]] = tail call i1 @ext()
29 ; CHECK-NEXT: br i1 [[COND]], label [[BB1:%.*]], label [[BB2:%.*]]
31 ; CHECK-NEXT: [[COND2:%.*]] = tail call i1 @ext()
32 ; CHECK-NEXT: br i1 [[COND2]], label [[BB3:%.*]], label [[BB2]]
34 ; CHECK-NEXT: ret i1 false
36 ; CHECK-NEXT: [[RES:%.*]] = tail call i1 @ext()
37 ; CHECK-NEXT: ret i1 [[RES]]
40 %cond = tail call i1 @ext()
41 br i1 %cond, label %bb1, label %bb2
44 %cond2 = tail call i1 @ext()
45 br i1 %cond2, label %bb3, label %bb2
48 %cond_merge = phi i1 [ %cond, %entry ], [ false, %bb1 ]
52 %res = tail call i1 @ext()
57 @gv = internal constant i8 7
58 define i8 @test3(ptr %a) nounwind {
59 ; CHECK-LABEL: @test3(
61 ; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[A:%.*]], @gv
62 ; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB:%.*]]
64 ; CHECK-NEXT: ret i8 0
66 ; CHECK-NEXT: [[SHOULD_BE_CONST:%.*]] = load i8, ptr [[A]], align 1
67 ; CHECK-NEXT: ret i8 [[SHOULD_BE_CONST]]
70 %cond = icmp eq ptr %a, @gv
71 br i1 %cond, label %bb2, label %bb
77 %should_be_const = load i8, ptr %a
78 ret i8 %should_be_const
82 define i32 @test4(i32) {
83 ; CHECK-LABEL: @test4(
84 ; CHECK-NEXT: EntryBlock:
85 ; CHECK-NEXT: [[DOTDEMORGAN:%.*]] = icmp sgt i32 [[TMP0:%.*]], 2
86 ; CHECK-NEXT: br i1 [[DOTDEMORGAN]], label [[GREATERTHANTWO:%.*]], label [[LESSTHANOREQUALTOTWO:%.*]]
87 ; CHECK: GreaterThanTwo:
88 ; CHECK-NEXT: br i1 false, label [[IMPOSSIBLE:%.*]], label [[NOTTWOANDGREATERTHANTWO:%.*]]
89 ; CHECK: NotTwoAndGreaterThanTwo:
90 ; CHECK-NEXT: ret i32 2
92 ; CHECK-NEXT: ret i32 1
93 ; CHECK: LessThanOrEqualToTwo:
94 ; CHECK-NEXT: ret i32 0
97 %.demorgan = icmp sgt i32 %0, 2
98 br i1 %.demorgan, label %GreaterThanTwo, label %LessThanOrEqualToTwo
102 br i1 %1, label %Impossible, label %NotTwoAndGreaterThanTwo
104 NotTwoAndGreaterThanTwo:
110 LessThanOrEqualToTwo:
115 define void @test5(ptr %x, ptr %y) {
116 ; CHECK-LABEL: @test5(
118 ; CHECK-NEXT: [[PRE:%.*]] = icmp eq ptr [[X:%.*]], null
119 ; CHECK-NEXT: br i1 [[PRE]], label [[RETURN:%.*]], label [[LOOP:%.*]]
121 ; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[F:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY:%.*]] ]
122 ; CHECK-NEXT: [[F]] = tail call ptr @f(ptr [[PHI]])
123 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne ptr [[F]], [[Y:%.*]]
124 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], ptr [[F]], ptr null
125 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq ptr [[SEL]], null
126 ; CHECK-NEXT: br i1 [[CMP2]], label [[RETURN]], label [[LOOP]]
128 ; CHECK-NEXT: ret void
131 %pre = icmp eq ptr %x, null
132 br i1 %pre, label %return, label %loop
135 %phi = phi ptr [ %sel, %loop ], [ %x, %entry ]
136 %f = tail call ptr @f(ptr %phi)
137 %cmp1 = icmp ne ptr %f, %y
138 %sel = select i1 %cmp1, ptr %f, ptr null
139 %cmp2 = icmp eq ptr %sel, null
140 br i1 %cmp2, label %return, label %loop
146 ; "false" case for CorrelatedValuePropagation
147 define void @loop1(ptr %x, ptr %y) {
148 ; CHECK-LABEL: @loop1(
150 ; CHECK-NEXT: br label [[LOOP:%.*]]
152 ; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[F:%.*]], [[LOOP]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
153 ; CHECK-NEXT: [[F]] = tail call ptr @f(ptr [[PHI]])
154 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne ptr [[F]], [[Y:%.*]]
155 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], ptr [[F]], ptr null
156 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq ptr [[SEL]], null
157 ; CHECK-NEXT: br i1 [[CMP2]], label [[RETURN:%.*]], label [[LOOP]]
159 ; CHECK-NEXT: ret void
165 %phi = phi ptr [ %sel, %loop ], [ %x, %entry ]
166 %f = tail call ptr @f(ptr %phi)
167 %cmp1 = icmp ne ptr %f, %y
168 %sel = select i1 %cmp1, ptr %f, ptr null
169 %cmp2 = icmp eq ptr %sel, null
170 br i1 %cmp2, label %return, label %loop
176 ; "true" case for CorrelatedValuePropagation
177 define void @loop2(ptr %x, ptr %y) {
178 ; CHECK-LABEL: @loop2(
180 ; CHECK-NEXT: br label [[LOOP:%.*]]
182 ; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[F:%.*]], [[LOOP]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
183 ; CHECK-NEXT: [[F]] = tail call ptr @f(ptr [[PHI]])
184 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq ptr [[F]], [[Y:%.*]]
185 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], ptr null, ptr [[F]]
186 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq ptr [[SEL]], null
187 ; CHECK-NEXT: br i1 [[CMP2]], label [[RETURN:%.*]], label [[LOOP]]
189 ; CHECK-NEXT: ret void
195 %phi = phi ptr [ %sel, %loop ], [ %x, %entry ]
196 %f = tail call ptr @f(ptr %phi)
197 %cmp1 = icmp eq ptr %f, %y
198 %sel = select i1 %cmp1, ptr null, ptr %f
199 %cmp2 = icmp eq ptr %sel, null
200 br i1 %cmp2, label %return, label %loop
206 define i32 @switch1(i32 %s) {
207 ; CHECK-LABEL: @switch1(
209 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[S:%.*]], 0
210 ; CHECK-NEXT: br i1 [[CMP]], label [[NEGATIVE:%.*]], label [[OUT:%.*]]
212 ; CHECK-NEXT: switch i32 [[S]], label [[OUT]] [
213 ; CHECK-NEXT: i32 -2, label [[NEXT:%.*]]
214 ; CHECK-NEXT: i32 -1, label [[NEXT]]
217 ; CHECK-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ -1, [[NEGATIVE]] ]
218 ; CHECK-NEXT: ret i32 [[P]]
220 ; CHECK-NEXT: ret i32 0
223 %cmp = icmp slt i32 %s, 0
224 br i1 %cmp, label %negative, label %out
227 switch i32 %s, label %out [
237 %p = phi i32 [ 1, %entry ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ]
241 %q = phi i32 [ 0, %negative ], [ 0, %negative ]
245 define i32 @switch2(i32 %s) {
246 ; CHECK-LABEL: @switch2(
248 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[S:%.*]], 0
249 ; CHECK-NEXT: br i1 [[CMP]], label [[POSITIVE:%.*]], label [[OUT:%.*]]
251 ; CHECK-NEXT: br label [[OUT]]
253 ; CHECK-NEXT: [[P:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 1, [[POSITIVE]] ]
254 ; CHECK-NEXT: ret i32 [[P]]
256 ; CHECK-NEXT: ret i32 0
259 %cmp = icmp sgt i32 %s, 0
260 br i1 %cmp, label %positive, label %out
263 switch i32 %s, label %out [
270 %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
274 %q = phi i32 [ 0, %positive ], [ 0, %positive ]
278 define i32 @switch3(i32 %s) {
279 ; CHECK-LABEL: @switch3(
281 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[S:%.*]], 0
282 ; CHECK-NEXT: br i1 [[CMP]], label [[POSITIVE:%.*]], label [[OUT:%.*]]
284 ; CHECK-NEXT: br label [[OUT]]
286 ; CHECK-NEXT: [[P:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 1, [[POSITIVE]] ]
287 ; CHECK-NEXT: ret i32 [[P]]
289 ; CHECK-NEXT: ret i32 0
292 %cmp = icmp sgt i32 %s, 0
293 br i1 %cmp, label %positive, label %out
296 switch i32 %s, label %out [
303 %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
307 %q = phi i32 [ 0, %positive ], [ 0, %positive ]
311 define void @switch4(i32 %s) {
312 ; CHECK-LABEL: @switch4(
314 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[S:%.*]], 0
315 ; CHECK-NEXT: br i1 [[CMP]], label [[ZERO:%.*]], label [[OUT:%.*]]
317 ; CHECK-NEXT: br label [[NEXT:%.*]]
319 ; CHECK-NEXT: ret void
321 ; CHECK-NEXT: ret void
324 %cmp = icmp eq i32 %s, 0
325 br i1 %cmp, label %zero, label %out
328 switch i32 %s, label %out [
341 define void @switch_nonzero_zext(i8 %s) {
342 ; CHECK-LABEL: @switch_nonzero_zext(
344 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[S:%.*]], 0
345 ; CHECK-NEXT: br i1 [[CMP]], label [[SWITCH:%.*]], label [[EXIT:%.*]]
347 ; CHECK-NEXT: [[S_EXT:%.*]] = zext i8 [[S]] to i32
348 ; CHECK-NEXT: br label [[EXIT]]
350 ; CHECK-NEXT: ret void
351 ; CHECK: unreachable:
352 ; CHECK-NEXT: ret void
355 %cmp = icmp ne i8 %s, 0
356 br i1 %cmp, label %switch, label %exit
359 %s.ext = zext i8 %s to i32
360 switch i32 %s.ext, label %exit [
361 i32 0, label %unreachable
373 define void @switch_assume_nonzero(i32 %s) {
374 ; CHECK-LABEL: @switch_assume_nonzero(
376 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[S:%.*]], 0
377 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
378 ; CHECK-NEXT: br label [[EXIT:%.*]]
380 ; CHECK-NEXT: ret void
381 ; CHECK: unreachable:
382 ; CHECK-NEXT: ret void
385 %cmp = icmp ne i32 %s, 0
386 call void @llvm.assume(i1 %cmp)
387 switch i32 %s, label %exit [
388 i32 0, label %unreachable
400 define void @switch_nonzero_phi(i1 %cond) {
401 ; CHECK-LABEL: @switch_nonzero_phi(
403 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
405 ; CHECK-NEXT: br label [[SWITCH:%.*]]
407 ; CHECK-NEXT: br label [[SWITCH]]
409 ; CHECK-NEXT: [[S:%.*]] = phi i32 [ 1, [[IF]] ], [ -1, [[ELSE]] ]
410 ; CHECK-NEXT: br label [[EXIT:%.*]]
412 ; CHECK-NEXT: ret void
413 ; CHECK: unreachable:
414 ; CHECK-NEXT: ret void
417 br i1 %cond, label %if, label %else
426 %s = phi i32 [ 1, %if ], [ -1, %else ]
427 switch i32 %s, label %exit [
428 i32 0, label %unreachable
440 define i32 @switch_range(i32 %cond) {
441 ; CHECK-LABEL: @switch_range(
443 ; CHECK-NEXT: [[S:%.*]] = urem i32 [[COND:%.*]], 3
444 ; CHECK-NEXT: [[S1:%.*]] = add nuw nsw i32 [[S]], 1
445 ; CHECK-NEXT: switch i32 [[S1]], label [[UNREACHABLE:%.*]] [
446 ; CHECK-NEXT: i32 1, label [[EXIT1:%.*]]
447 ; CHECK-NEXT: i32 2, label [[EXIT2:%.*]]
448 ; CHECK-NEXT: i32 3, label [[EXIT1]]
451 ; CHECK-NEXT: ret i32 1
453 ; CHECK-NEXT: ret i32 2
454 ; CHECK: unreachable:
455 ; CHECK-NEXT: ret i32 0
458 %s = urem i32 %cond, 3
460 switch i32 %s1, label %unreachable [
474 ; If the cases do not cover the entire range of the
475 ; switch condition, we should not change the default.
477 define i32 @switch_range_not_full(i32 %cond) {
478 ; CHECK-LABEL: @switch_range_not_full(
480 ; CHECK-NEXT: [[S:%.*]] = urem i32 [[COND:%.*]], 3
481 ; CHECK-NEXT: [[S1:%.*]] = add nuw nsw i32 [[S]], 1
482 ; CHECK-NEXT: switch i32 [[S1]], label [[UNREACHABLE:%.*]] [
483 ; CHECK-NEXT: i32 1, label [[EXIT1:%.*]]
484 ; CHECK-NEXT: i32 3, label [[EXIT2:%.*]]
487 ; CHECK-NEXT: ret i32 1
489 ; CHECK-NEXT: ret i32 2
490 ; CHECK: unreachable:
491 ; CHECK-NEXT: ret i32 0
494 %s = urem i32 %cond, 3
496 switch i32 %s1, label %unreachable [
511 define i8 @switch_defaultdest_multipleuse(i8 %t0) {
512 ; CHECK-LABEL: @switch_defaultdest_multipleuse(
514 ; CHECK-NEXT: [[O:%.*]] = or i8 [[T0:%.*]], 1
515 ; CHECK-NEXT: [[R:%.*]] = srem i8 1, [[O]]
516 ; CHECK-NEXT: switch i8 [[R]], label [[EXIT:%.*]] [
517 ; CHECK-NEXT: i8 0, label [[EXIT]]
518 ; CHECK-NEXT: i8 1, label [[EXIT]]
521 ; CHECK-NEXT: ret i8 0
526 switch i8 %r, label %exit [
535 define i1 @arg_attribute(ptr nonnull %a) {
536 ; CHECK-LABEL: @arg_attribute(
537 ; CHECK-NEXT: ret i1 false
539 %cmp = icmp eq i8* %a, null
543 declare nonnull ptr @return_nonnull()
544 define i1 @call_attribute() {
545 ; CHECK-LABEL: @call_attribute(
546 ; CHECK-NEXT: [[A:%.*]] = call ptr @return_nonnull()
547 ; CHECK-NEXT: ret i1 false
549 %a = call i8* @return_nonnull()
550 %cmp = icmp eq ptr %a, null
554 define i1 @umin(i32 %a, i32 %b) {
555 ; CHECK-LABEL: @umin(
557 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 5
558 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
560 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20
561 ; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
563 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ult i32 [[A]], [[B]]
564 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
565 ; CHECK-NEXT: ret i1 false
567 ; CHECK-NEXT: ret i1 false
570 %cmp = icmp ult i32 %a, 5
571 br i1 %cmp, label %a_guard, label %out
574 %cmp2 = icmp ult i32 %b, 20
575 br i1 %cmp2, label %b_guard, label %out
578 %sel_cmp = icmp ult i32 %a, %b
579 %min = select i1 %sel_cmp, i32 %a, i32 %b
580 %res = icmp eq i32 %min, 7
586 define i1 @smin(i32 %a, i32 %b) {
587 ; CHECK-LABEL: @smin(
589 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 5
590 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
592 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 20
593 ; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
595 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ule i32 [[A]], [[B]]
596 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
597 ; CHECK-NEXT: ret i1 false
599 ; CHECK-NEXT: ret i1 false
602 %cmp = icmp ult i32 %a, 5
603 br i1 %cmp, label %a_guard, label %out
606 %cmp2 = icmp ult i32 %b, 20
607 br i1 %cmp2, label %b_guard, label %out
610 %sel_cmp = icmp sle i32 %a, %b
611 %min = select i1 %sel_cmp, i32 %a, i32 %b
612 %res = icmp eq i32 %min, 7
618 define i1 @smax(i32 %a, i32 %b) {
619 ; CHECK-LABEL: @smax(
621 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5
622 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
624 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20
625 ; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
627 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]]
628 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
629 ; CHECK-NEXT: ret i1 false
631 ; CHECK-NEXT: ret i1 false
634 %cmp = icmp sgt i32 %a, 5
635 br i1 %cmp, label %a_guard, label %out
638 %cmp2 = icmp sgt i32 %b, 20
639 br i1 %cmp2, label %b_guard, label %out
642 %sel_cmp = icmp sge i32 %a, %b
643 %max = select i1 %sel_cmp, i32 %a, i32 %b
644 %res = icmp eq i32 %max, 7
650 define i1 @umax(i32 %a, i32 %b) {
651 ; CHECK-LABEL: @umax(
653 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 5
654 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
656 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[B:%.*]], 20
657 ; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
659 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]]
660 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
661 ; CHECK-NEXT: ret i1 false
663 ; CHECK-NEXT: ret i1 false
666 %cmp = icmp sgt i32 %a, 5
667 br i1 %cmp, label %a_guard, label %out
670 %cmp2 = icmp sgt i32 %b, 20
671 br i1 %cmp2, label %b_guard, label %out
674 %sel_cmp = icmp uge i32 %a, %b
675 %max = select i1 %sel_cmp, i32 %a, i32 %b
676 %res = icmp eq i32 %max, 7
682 define i1 @umin_lhs_overdefined_rhs_const(i32 %a) {
683 ; CHECK-LABEL: @umin_lhs_overdefined_rhs_const(
684 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 42
685 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 42
686 ; CHECK-NEXT: ret i1 true
688 %cmp = icmp ult i32 %a, 42
689 %sel = select i1 %cmp, i32 %a, i32 42
690 %cmp2 = icmp ule i32 %sel, 42
694 define i1 @umin_rhs_overdefined_lhs_const(i32 %a) {
695 ; CHECK-LABEL: @umin_rhs_overdefined_lhs_const(
696 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A:%.*]], 42
697 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 42, i32 [[A]]
698 ; CHECK-NEXT: ret i1 true
700 %cmp = icmp uge i32 %a, 42
701 %sel = select i1 %cmp, i32 42, i32 %a
702 %cmp2 = icmp ule i32 %sel, 42
706 define i1 @umin_lhs_overdefined_rhs_range(i32 %a, i32 %b) {
707 ; CHECK-LABEL: @umin_lhs_overdefined_rhs_range(
708 ; CHECK-NEXT: [[ASSUME:%.*]] = icmp ult i32 [[B:%.*]], 42
709 ; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]])
710 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[B]]
711 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[B]]
712 ; CHECK-NEXT: ret i1 true
714 %assume = icmp ult i32 %b, 42
715 call void @llvm.assume(i1 %assume)
716 %cmp = icmp ult i32 %a, %b
717 %sel = select i1 %cmp, i32 %a, i32 %b
718 %cmp2 = icmp ult i32 %sel, 42
722 define i1 @umin_rhs_overdefined_lhs_range(i32 %a, i32 %b) {
723 ; CHECK-LABEL: @umin_rhs_overdefined_lhs_range(
724 ; CHECK-NEXT: [[ASSUME:%.*]] = icmp ult i32 [[B:%.*]], 42
725 ; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]])
726 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A:%.*]], [[B]]
727 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[B]], i32 [[A]]
728 ; CHECK-NEXT: ret i1 true
730 %assume = icmp ult i32 %b, 42
731 call void @llvm.assume(i1 %assume)
732 %cmp = icmp uge i32 %a, %b
733 %sel = select i1 %cmp, i32 %b, i32 %a
734 %cmp2 = icmp ult i32 %sel, 42
738 define i1 @clamp_low1(i32 noundef %a) {
739 ; CHECK-LABEL: @clamp_low1(
741 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
742 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
744 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5
745 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1
746 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
747 ; CHECK-NEXT: ret i1 false
749 ; CHECK-NEXT: ret i1 false
752 %cmp = icmp sge i32 %a, 5
753 br i1 %cmp, label %a_guard, label %out
756 %sel_cmp = icmp eq i32 %a, 5
757 %add = add i32 %a, -1
758 %sel = select i1 %sel_cmp, i32 5, i32 %add
759 %res = icmp eq i32 %sel, 4
765 define i1 @clamp_low2(i32 noundef %a) {
766 ; CHECK-LABEL: @clamp_low2(
768 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
769 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
771 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
772 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1
773 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
774 ; CHECK-NEXT: ret i1 false
776 ; CHECK-NEXT: ret i1 false
779 %cmp = icmp sge i32 %a, 5
780 br i1 %cmp, label %a_guard, label %out
783 %sel_cmp = icmp ne i32 %a, 5
784 %add = add i32 %a, -1
785 %sel = select i1 %sel_cmp, i32 %add, i32 5
786 %res = icmp eq i32 %sel, 4
792 define i1 @clamp_low3(i32 noundef %a) {
793 ; CHECK-LABEL: @clamp_low3(
795 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
796 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
798 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ugt i32 [[A]], 5
799 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1
800 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
801 ; CHECK-NEXT: ret i1 false
803 ; CHECK-NEXT: ret i1 false
806 %cmp = icmp sge i32 %a, 5
807 br i1 %cmp, label %a_guard, label %out
810 %sel_cmp = icmp sgt i32 %a, 5
811 %add = add i32 %a, -1
812 %sel = select i1 %sel_cmp, i32 %add, i32 5
813 %res = icmp eq i32 %sel, 4
819 define i1 @clamp_low4(i32 noundef %a) {
820 ; CHECK-LABEL: @clamp_low4(
822 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A:%.*]], 5
823 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
825 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ule i32 [[A]], 5
826 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1
827 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
828 ; CHECK-NEXT: ret i1 false
830 ; CHECK-NEXT: ret i1 false
833 %cmp = icmp sge i32 %a, 5
834 br i1 %cmp, label %a_guard, label %out
837 %sel_cmp = icmp sle i32 %a, 5
838 %add = add i32 %a, -1
839 %sel = select i1 %sel_cmp, i32 5, i32 %add
840 %res = icmp eq i32 %sel, 4
846 define i1 @clamp_high1(i32 noundef %a) {
847 ; CHECK-LABEL: @clamp_high1(
849 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
850 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
852 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5
853 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
854 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
855 ; CHECK-NEXT: ret i1 false
857 ; CHECK-NEXT: ret i1 false
860 %cmp = icmp sle i32 %a, 5
861 br i1 %cmp, label %a_guard, label %out
864 %sel_cmp = icmp eq i32 %a, 5
866 %sel = select i1 %sel_cmp, i32 5, i32 %add
867 %res = icmp eq i32 %sel, 6
873 define i1 @clamp_high2(i32 noundef %a) {
874 ; CHECK-LABEL: @clamp_high2(
876 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
877 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
879 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
880 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
881 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
882 ; CHECK-NEXT: ret i1 false
884 ; CHECK-NEXT: ret i1 false
887 %cmp = icmp sle i32 %a, 5
888 br i1 %cmp, label %a_guard, label %out
891 %sel_cmp = icmp ne i32 %a, 5
893 %sel = select i1 %sel_cmp, i32 %add, i32 5
894 %res = icmp eq i32 %sel, 6
900 define i1 @clamp_high3(i32 noundef %a) {
901 ; CHECK-LABEL: @clamp_high3(
903 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
904 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
906 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp slt i32 [[A]], 5
907 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
908 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
909 ; CHECK-NEXT: ret i1 false
911 ; CHECK-NEXT: ret i1 false
914 %cmp = icmp sle i32 %a, 5
915 br i1 %cmp, label %a_guard, label %out
918 %sel_cmp = icmp slt i32 %a, 5
920 %sel = select i1 %sel_cmp, i32 %add, i32 5
921 %res = icmp eq i32 %sel, 6
927 define i1 @clamp_high4(i32 noundef %a) {
928 ; CHECK-LABEL: @clamp_high4(
930 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
931 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
933 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sge i32 [[A]], 5
934 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
935 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
936 ; CHECK-NEXT: ret i1 false
938 ; CHECK-NEXT: ret i1 false
941 %cmp = icmp sle i32 %a, 5
942 br i1 %cmp, label %a_guard, label %out
945 %sel_cmp = icmp sge i32 %a, 5
947 %sel = select i1 %sel_cmp, i32 5, i32 %add
948 %res = icmp eq i32 %sel, 6
954 ; Just showing arbitrary constants work, not really a clamp
955 define i1 @not_clamp_high(i32 noundef %a) {
956 ; CHECK-LABEL: @not_clamp_high(
958 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A:%.*]], 5
959 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
961 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
962 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 100
963 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
964 ; CHECK-NEXT: ret i1 false
966 ; CHECK-NEXT: ret i1 false
969 %cmp = icmp sle i32 %a, 5
970 br i1 %cmp, label %a_guard, label %out
973 %sel_cmp = icmp ne i32 %a, 5
974 %add = add i32 %a, 100
975 %sel = select i1 %sel_cmp, i32 %add, i32 5
976 %res = icmp eq i32 %sel, 105
982 define void @abs1(i32 %a, ptr %p) {
983 ; CHECK-LABEL: @abs1(
985 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
986 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
987 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
988 ; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
990 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]]
991 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0
992 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
993 ; CHECK-NEXT: store i1 true, ptr [[P:%.*]], align 1
994 ; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[ABS]], 19
995 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
996 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
997 ; CHECK-NEXT: [[C4:%.*]] = icmp uge i32 [[ABS]], 1
998 ; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
999 ; CHECK-NEXT: br label [[EXIT]]
1001 ; CHECK-NEXT: ret void
1004 %cmp1 = icmp slt i32 %a, 10
1005 %cmp2 = icmp sgt i32 %a, -20
1006 %and = and i1 %cmp1, %cmp2
1007 br i1 %and, label %guard, label %exit
1010 %sub = sub i32 0, %a
1011 %cmp = icmp slt i32 %a, 0
1012 %abs = select i1 %cmp, i32 %sub, i32 %a
1013 %c1 = icmp slt i32 %abs, 20
1014 store i1 %c1, ptr %p
1015 %c2 = icmp slt i32 %abs, 19
1016 store i1 %c2, ptr %p
1017 %c3 = icmp sge i32 %abs, 0
1018 store i1 %c3, ptr %p
1019 %c4 = icmp sge i32 %abs, 1
1020 store i1 %c4, ptr %p
1027 define void @abs2(i32 %a, ptr %p) {
1028 ; CHECK-LABEL: @abs2(
1029 ; CHECK-NEXT: entry:
1030 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
1031 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1032 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1033 ; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1035 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]]
1036 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], 0
1037 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]
1038 ; CHECK-NEXT: store i1 true, ptr [[P:%.*]], align 1
1039 ; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[ABS]], 19
1040 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1041 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1042 ; CHECK-NEXT: [[C4:%.*]] = icmp uge i32 [[ABS]], 1
1043 ; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
1044 ; CHECK-NEXT: br label [[EXIT]]
1046 ; CHECK-NEXT: ret void
1049 %cmp1 = icmp slt i32 %a, 10
1050 %cmp2 = icmp sgt i32 %a, -20
1051 %and = and i1 %cmp1, %cmp2
1052 br i1 %and, label %guard, label %exit
1055 %sub = sub i32 0, %a
1056 %cmp = icmp sge i32 %a, 0
1057 %abs = select i1 %cmp, i32 %a, i32 %sub
1058 %c1 = icmp slt i32 %abs, 20
1059 store i1 %c1, ptr %p
1060 %c2 = icmp slt i32 %abs, 19
1061 store i1 %c2, ptr %p
1062 %c3 = icmp sge i32 %abs, 0
1063 store i1 %c3, ptr %p
1064 %c4 = icmp sge i32 %abs, 1
1065 store i1 %c4, ptr %p
1072 define void @nabs1(i32 %a, ptr %p) {
1073 ; CHECK-LABEL: @nabs1(
1074 ; CHECK-NEXT: entry:
1075 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
1076 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1077 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1078 ; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1080 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]]
1081 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 0
1082 ; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
1083 ; CHECK-NEXT: store i1 true, ptr [[P:%.*]], align 1
1084 ; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[NABS]], -19
1085 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1086 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1087 ; CHECK-NEXT: [[C4:%.*]] = icmp sle i32 [[NABS]], -1
1088 ; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
1089 ; CHECK-NEXT: br label [[EXIT]]
1091 ; CHECK-NEXT: ret void
1094 %cmp1 = icmp slt i32 %a, 10
1095 %cmp2 = icmp sgt i32 %a, -20
1096 %and = and i1 %cmp1, %cmp2
1097 br i1 %and, label %guard, label %exit
1100 %sub = sub i32 0, %a
1101 %cmp = icmp sgt i32 %a, 0
1102 %nabs = select i1 %cmp, i32 %sub, i32 %a
1103 %c1 = icmp sgt i32 %nabs, -20
1104 store i1 %c1, ptr %p
1105 %c2 = icmp sgt i32 %nabs, -19
1106 store i1 %c2, ptr %p
1107 %c3 = icmp sle i32 %nabs, 0
1108 store i1 %c3, ptr %p
1109 %c4 = icmp sle i32 %nabs, -1
1110 store i1 %c4, ptr %p
1117 define void @nabs2(i32 %a, ptr %p) {
1118 ; CHECK-LABEL: @nabs2(
1119 ; CHECK-NEXT: entry:
1120 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], 10
1121 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1122 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1123 ; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1125 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]]
1126 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0
1127 ; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]
1128 ; CHECK-NEXT: store i1 true, ptr [[P:%.*]], align 1
1129 ; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[NABS]], -19
1130 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1131 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1132 ; CHECK-NEXT: [[C4:%.*]] = icmp sle i32 [[NABS]], -1
1133 ; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
1134 ; CHECK-NEXT: br label [[EXIT]]
1136 ; CHECK-NEXT: ret void
1139 %cmp1 = icmp slt i32 %a, 10
1140 %cmp2 = icmp sgt i32 %a, -20
1141 %and = and i1 %cmp1, %cmp2
1142 br i1 %and, label %guard, label %exit
1145 %sub = sub i32 0, %a
1146 %cmp = icmp slt i32 %a, 0
1147 %nabs = select i1 %cmp, i32 %a, i32 %sub
1148 %c1 = icmp sgt i32 %nabs, -20
1149 store i1 %c1, ptr %p
1150 %c2 = icmp sgt i32 %nabs, -19
1151 store i1 %c2, ptr %p
1152 %c3 = icmp sle i32 %nabs, 0
1153 store i1 %c3, ptr %p
1154 %c4 = icmp sle i32 %nabs, -1
1155 store i1 %c4, ptr %p
1162 define i1 @zext_unknown(i8 %a) {
1163 ; CHECK-LABEL: @zext_unknown(
1164 ; CHECK-NEXT: entry:
1165 ; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A:%.*]] to i32
1166 ; CHECK-NEXT: ret i1 true
1169 %a32 = zext i8 %a to i32
1170 %cmp = icmp sle i32 %a32, 256
1174 define i1 @trunc_unknown(i32 %a) {
1175 ; CHECK-LABEL: @trunc_unknown(
1176 ; CHECK-NEXT: entry:
1177 ; CHECK-NEXT: [[A8:%.*]] = trunc i32 [[A:%.*]] to i8
1178 ; CHECK-NEXT: [[A32:%.*]] = sext i8 [[A8]] to i32
1179 ; CHECK-NEXT: ret i1 true
1182 %a8 = trunc i32 %a to i8
1183 %a32 = sext i8 %a8 to i32
1184 %cmp = icmp sle i32 %a32, 128
1188 define void @trunc_icmp_ule(i32 %x, ptr %p) {
1189 ; CHECK-LABEL: @trunc_icmp_ule(
1190 ; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
1191 ; CHECK-NEXT: [[C:%.*]] = icmp uge i8 [[T]], 5
1192 ; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1194 ; CHECK-NEXT: store i1 true, ptr [[P:%.*]], align 1
1195 ; CHECK-NEXT: [[C2:%.*]] = icmp ugt i32 [[X]], 5
1196 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1197 ; CHECK-NEXT: [[C3:%.*]] = icmp ule i32 [[X]], 5
1198 ; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 1
1199 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1200 ; CHECK-NEXT: ret void
1202 ; CHECK-NEXT: [[C1_2:%.*]] = icmp uge i32 [[X]], 5
1203 ; CHECK-NEXT: store i1 [[C1_2]], ptr [[P]], align 1
1204 ; CHECK-NEXT: [[C2_2:%.*]] = icmp ugt i32 [[X]], 5
1205 ; CHECK-NEXT: store i1 [[C2_2]], ptr [[P]], align 1
1206 ; CHECK-NEXT: [[C3_2:%.*]] = icmp ule i32 [[X]], 5
1207 ; CHECK-NEXT: store i1 [[C3_2]], ptr [[P]], align 1
1208 ; CHECK-NEXT: [[C4_2:%.*]] = icmp ult i32 [[X]], 5
1209 ; CHECK-NEXT: store i1 [[C4_2]], ptr [[P]], align 1
1210 ; CHECK-NEXT: ret void
1212 %t = trunc i32 %x to i8
1213 %c = icmp uge i8 %t, 5
1214 br i1 %c, label %true, label %false
1217 %c1 = icmp uge i32 %x, 5
1218 store i1 %c1, ptr %p
1219 %c2 = icmp ugt i32 %x, 5
1220 store i1 %c2, ptr %p
1221 %c3 = icmp ule i32 %x, 5
1222 store i1 %c3, ptr %p
1223 %c4 = icmp ult i32 %x, 5
1224 store i1 %c4, ptr %p
1228 %c1.2 = icmp uge i32 %x, 5
1229 store i1 %c1.2, ptr %p
1230 %c2.2 = icmp ugt i32 %x, 5
1231 store i1 %c2.2, ptr %p
1232 %c3.2 = icmp ule i32 %x, 5
1233 store i1 %c3.2, ptr %p
1234 %c4.2 = icmp ult i32 %x, 5
1235 store i1 %c4.2, ptr %p
1239 define void @trunc_icmp_eq(i32 %x, ptr %p) {
1240 ; CHECK-LABEL: @trunc_icmp_eq(
1241 ; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i8
1242 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[T]], 5
1243 ; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1245 ; CHECK-NEXT: store i1 true, ptr [[P:%.*]], align 1
1246 ; CHECK-NEXT: [[C2:%.*]] = icmp ugt i32 [[X]], 5
1247 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1248 ; CHECK-NEXT: [[C3:%.*]] = icmp ule i32 [[X]], 5
1249 ; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 1
1250 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1251 ; CHECK-NEXT: ret void
1253 ; CHECK-NEXT: [[C1_2:%.*]] = icmp uge i32 [[X]], 5
1254 ; CHECK-NEXT: store i1 [[C1_2]], ptr [[P]], align 1
1255 ; CHECK-NEXT: [[C2_2:%.*]] = icmp ugt i32 [[X]], 5
1256 ; CHECK-NEXT: store i1 [[C2_2]], ptr [[P]], align 1
1257 ; CHECK-NEXT: [[C3_2:%.*]] = icmp ule i32 [[X]], 5
1258 ; CHECK-NEXT: store i1 [[C3_2]], ptr [[P]], align 1
1259 ; CHECK-NEXT: [[C4_2:%.*]] = icmp ult i32 [[X]], 5
1260 ; CHECK-NEXT: store i1 [[C4_2]], ptr [[P]], align 1
1261 ; CHECK-NEXT: ret void
1263 %t = trunc i32 %x to i8
1264 %c = icmp eq i8 %t, 5
1265 br i1 %c, label %true, label %false
1268 %c1 = icmp uge i32 %x, 5
1269 store i1 %c1, ptr %p
1270 %c2 = icmp ugt i32 %x, 5
1271 store i1 %c2, ptr %p
1272 %c3 = icmp ule i32 %x, 5
1273 store i1 %c3, ptr %p
1274 %c4 = icmp ult i32 %x, 5
1275 store i1 %c4, ptr %p
1279 %c1.2 = icmp uge i32 %x, 5
1280 store i1 %c1.2, ptr %p
1281 %c2.2 = icmp ugt i32 %x, 5
1282 store i1 %c2.2, ptr %p
1283 %c3.2 = icmp ule i32 %x, 5
1284 store i1 %c3.2, ptr %p
1285 %c4.2 = icmp ult i32 %x, 5
1286 store i1 %c4.2, ptr %p
1290 ; TODO: missed optimization
1291 ; Make sure we exercise non-integer inputs to unary operators (i.e. crash check).
1292 define i1 @bitcast_unknown(float %a) {
1293 ; CHECK-LABEL: @bitcast_unknown(
1294 ; CHECK-NEXT: entry:
1295 ; CHECK-NEXT: [[A32:%.*]] = bitcast float [[A:%.*]] to i32
1296 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A32]], 128
1297 ; CHECK-NEXT: ret i1 [[CMP]]
1300 %a32 = bitcast float %a to i32
1301 %cmp = icmp sle i32 %a32, 128
1305 define i1 @bitcast_unknown2(ptr %p) {
1306 ; CHECK-LABEL: @bitcast_unknown2(
1307 ; CHECK-NEXT: entry:
1308 ; CHECK-NEXT: [[P64:%.*]] = ptrtoint ptr [[P:%.*]] to i64
1309 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[P64]], 128
1310 ; CHECK-NEXT: ret i1 [[CMP]]
1313 %p64 = ptrtoint ptr %p to i64
1314 %cmp = icmp sle i64 %p64, 128
1319 define i1 @and_unknown(i32 %a) {
1320 ; CHECK-LABEL: @and_unknown(
1321 ; CHECK-NEXT: entry:
1322 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 128
1323 ; CHECK-NEXT: ret i1 true
1326 %and = and i32 %a, 128
1327 %cmp = icmp sle i32 %and, 128
1331 define i1 @lshr_unknown(i32 %a) {
1332 ; CHECK-LABEL: @lshr_unknown(
1333 ; CHECK-NEXT: entry:
1334 ; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[A:%.*]], 30
1335 ; CHECK-NEXT: ret i1 true
1338 %and = lshr i32 %a, 30
1339 %cmp = icmp sle i32 %and, 128
1343 define i1 @urem_unknown(i32 %a) {
1344 ; CHECK-LABEL: @urem_unknown(
1345 ; CHECK-NEXT: entry:
1346 ; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[A:%.*]], 30
1347 ; CHECK-NEXT: ret i1 true
1350 %urem = urem i32 %a, 30
1351 %cmp = icmp ult i32 %urem, 30
1355 define i1 @srem_unknown(i32 %a) {
1356 ; CHECK-LABEL: @srem_unknown(
1357 ; CHECK-NEXT: entry:
1358 ; CHECK-NEXT: [[SREM:%.*]] = srem i32 [[A:%.*]], 30
1359 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1361 ; CHECK-NEXT: ret i1 true
1363 ; CHECK-NEXT: ret i1 true
1366 %srem = srem i32 %a, 30
1367 %cmp1 = icmp slt i32 %srem, 30
1368 %cmp2 = icmp sgt i32 %srem, -30
1369 br i1 undef, label %exit1, label %exit2
1376 define i1 @sdiv_unknown(i32 %a) {
1377 ; CHECK-LABEL: @sdiv_unknown(
1378 ; CHECK-NEXT: entry:
1379 ; CHECK-NEXT: [[SREM:%.*]] = sdiv i32 [[A:%.*]], 123
1380 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1382 ; CHECK-NEXT: ret i1 true
1384 ; CHECK-NEXT: ret i1 true
1387 %srem = sdiv i32 %a, 123
1388 %cmp1 = icmp slt i32 %srem, 17459217
1389 %cmp2 = icmp sgt i32 %srem, -17459217
1390 br i1 undef, label %exit1, label %exit2
1397 define i1 @uadd_sat_unknown(i32 %a) {
1398 ; CHECK-LABEL: @uadd_sat_unknown(
1399 ; CHECK-NEXT: entry:
1400 ; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[A:%.*]], i32 100)
1401 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[VAL]], 100
1402 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1404 ; CHECK-NEXT: ret i1 true
1406 ; CHECK-NEXT: ret i1 [[CMP2]]
1409 %val = call i32 @llvm.uadd.sat.i32(i32 %a, i32 100)
1410 %cmp1 = icmp uge i32 %val, 100
1411 %cmp2 = icmp ugt i32 %val, 100
1412 br i1 undef, label %exit1, label %exit2
1419 define i1 @usub_sat_unknown(i32 %a) {
1420 ; CHECK-LABEL: @usub_sat_unknown(
1421 ; CHECK-NEXT: entry:
1422 ; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 100)
1423 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[VAL]], -101
1424 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1426 ; CHECK-NEXT: ret i1 true
1428 ; CHECK-NEXT: ret i1 [[CMP2]]
1431 %val = call i32 @llvm.usub.sat.i32(i32 %a, i32 100)
1432 %cmp1 = icmp ule i32 %val, 4294967195
1433 %cmp2 = icmp ult i32 %val, 4294967195
1434 br i1 undef, label %exit1, label %exit2
1441 define i1 @sadd_sat_unknown(i32 %a) {
1442 ; CHECK-LABEL: @sadd_sat_unknown(
1443 ; CHECK-NEXT: entry:
1444 ; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A:%.*]], i32 100)
1445 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[VAL]], -2147483548
1446 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1448 ; CHECK-NEXT: ret i1 true
1450 ; CHECK-NEXT: ret i1 [[CMP2]]
1453 %val = call i32 @llvm.sadd.sat.i32(i32 %a, i32 100)
1454 %cmp1 = icmp sge i32 %val, -2147483548
1455 %cmp2 = icmp sgt i32 %val, -2147483548
1456 br i1 undef, label %exit1, label %exit2
1463 define i1 @ssub_sat_unknown(i32 %a) {
1464 ; CHECK-LABEL: @ssub_sat_unknown(
1465 ; CHECK-NEXT: entry:
1466 ; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 100)
1467 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[VAL]], 2147483547
1468 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1470 ; CHECK-NEXT: ret i1 true
1472 ; CHECK-NEXT: ret i1 [[CMP2]]
1475 %val = call i32 @llvm.ssub.sat.i32(i32 %a, i32 100)
1476 %cmp1 = icmp sle i32 %val, 2147483547
1477 %cmp2 = icmp slt i32 %val, 2147483547
1478 br i1 undef, label %exit1, label %exit2
1485 define void @select_and(i32 %a, ptr %p) {
1486 ; CHECK-LABEL: @select_and(
1487 ; CHECK-NEXT: entry:
1488 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10
1489 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1490 ; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1491 ; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1493 ; CHECK-NEXT: store i1 false, ptr [[P:%.*]], align 1
1494 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1495 ; CHECK-NEXT: br label [[EXIT]]
1497 ; CHECK-NEXT: ret void
1500 %cmp1 = icmp sgt i32 %a, -10
1501 %cmp2 = icmp slt i32 %a, 10
1502 %and = select i1 %cmp1, i1 %cmp2, i1 false
1503 br i1 %and, label %guard, label %exit
1506 %c1 = icmp sgt i32 %a, 20
1507 store i1 %c1, ptr %p
1508 %c2 = icmp slt i32 %a, -20
1509 store i1 %c2, ptr %p
1516 define void @select_and_wrong_const(i32 %a, ptr %p) {
1517 ; CHECK-LABEL: @select_and_wrong_const(
1518 ; CHECK-NEXT: entry:
1519 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10
1520 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1521 ; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true
1522 ; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1524 ; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20
1525 ; CHECK-NEXT: store i1 [[C1]], ptr [[P:%.*]], align 1
1526 ; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20
1527 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1528 ; CHECK-NEXT: br label [[EXIT]]
1530 ; CHECK-NEXT: ret void
1533 %cmp1 = icmp sgt i32 %a, -10
1534 %cmp2 = icmp slt i32 %a, 10
1535 %and = select i1 %cmp1, i1 %cmp2, i1 true
1536 br i1 %and, label %guard, label %exit
1539 %c1 = icmp sgt i32 %a, 20
1540 store i1 %c1, ptr %p
1541 %c2 = icmp slt i32 %a, -20
1542 store i1 %c2, ptr %p
1549 define void @select_and_wrong_operand(i32 %a, ptr %p) {
1550 ; CHECK-LABEL: @select_and_wrong_operand(
1551 ; CHECK-NEXT: entry:
1552 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -10
1553 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1554 ; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]
1555 ; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1557 ; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20
1558 ; CHECK-NEXT: store i1 [[C1]], ptr [[P:%.*]], align 1
1559 ; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20
1560 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1561 ; CHECK-NEXT: br label [[EXIT]]
1563 ; CHECK-NEXT: ret void
1566 %cmp1 = icmp sgt i32 %a, -10
1567 %cmp2 = icmp slt i32 %a, 10
1568 %and = select i1 %cmp1, i1 false, i1 %cmp2
1569 br i1 %and, label %guard, label %exit
1572 %c1 = icmp sgt i32 %a, 20
1573 store i1 %c1, ptr %p
1574 %c2 = icmp slt i32 %a, -20
1575 store i1 %c2, ptr %p
1582 define void @select_or(i32 %a, ptr %p) {
1583 ; CHECK-LABEL: @select_or(
1584 ; CHECK-NEXT: entry:
1585 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10
1586 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1587 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]]
1588 ; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1590 ; CHECK-NEXT: store i1 false, ptr [[P:%.*]], align 1
1591 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1592 ; CHECK-NEXT: br label [[EXIT]]
1594 ; CHECK-NEXT: ret void
1597 %cmp1 = icmp slt i32 %a, -10
1598 %cmp2 = icmp sgt i32 %a, 10
1599 %or = select i1 %cmp1, i1 true, i1 %cmp2
1600 br i1 %or, label %exit, label %guard
1603 %c1 = icmp sgt i32 %a, 20
1604 store i1 %c1, ptr %p
1605 %c2 = icmp slt i32 %a, -20
1606 store i1 %c2, ptr %p
1613 define void @select_or_wrong_const(i32 %a, ptr %p) {
1614 ; CHECK-LABEL: @select_or_wrong_const(
1615 ; CHECK-NEXT: entry:
1616 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10
1617 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1618 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]
1619 ; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1621 ; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20
1622 ; CHECK-NEXT: store i1 [[C1]], ptr [[P:%.*]], align 1
1623 ; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20
1624 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1625 ; CHECK-NEXT: br label [[EXIT]]
1627 ; CHECK-NEXT: ret void
1630 %cmp1 = icmp slt i32 %a, -10
1631 %cmp2 = icmp sgt i32 %a, 10
1632 %or = select i1 %cmp1, i1 false, i1 %cmp2
1633 br i1 %or, label %exit, label %guard
1636 %c1 = icmp sgt i32 %a, 20
1637 store i1 %c1, ptr %p
1638 %c2 = icmp slt i32 %a, -20
1639 store i1 %c2, ptr %p
1646 define void @select_or_wrong_operand(i32 %a, ptr %p) {
1647 ; CHECK-LABEL: @select_or_wrong_operand(
1648 ; CHECK-NEXT: entry:
1649 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A:%.*]], -10
1650 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1651 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true
1652 ; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1654 ; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20
1655 ; CHECK-NEXT: store i1 [[C1]], ptr [[P:%.*]], align 1
1656 ; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20
1657 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1658 ; CHECK-NEXT: br label [[EXIT]]
1660 ; CHECK-NEXT: ret void
1663 %cmp1 = icmp slt i32 %a, -10
1664 %cmp2 = icmp sgt i32 %a, 10
1665 %or = select i1 %cmp1, i1 %cmp2, i1 true
1666 br i1 %or, label %exit, label %guard
1669 %c1 = icmp sgt i32 %a, 20
1670 store i1 %c1, ptr %p
1671 %c2 = icmp slt i32 %a, -20
1672 store i1 %c2, ptr %p
1679 define void @or_union(i32 %a, ptr %p) {
1680 ; CHECK-LABEL: @or_union(
1681 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 10
1682 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 12
1683 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
1684 ; CHECK-NEXT: br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1686 ; CHECK-NEXT: store i1 false, ptr [[P:%.*]], align 1
1687 ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[A]], 10
1688 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1689 ; CHECK-NEXT: [[C3:%.*]] = icmp eq i32 [[A]], 11
1690 ; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 1
1691 ; CHECK-NEXT: [[C4:%.*]] = icmp eq i32 [[A]], 12
1692 ; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
1693 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1694 ; CHECK-NEXT: br label [[EXIT]]
1696 ; CHECK-NEXT: ret void
1698 %cmp1 = icmp eq i32 %a, 10
1699 %cmp2 = icmp eq i32 %a, 12
1700 %or = or i1 %cmp1, %cmp2
1701 br i1 %or, label %guard, label %exit
1704 %c1 = icmp eq i32 %a, 9
1705 store i1 %c1, ptr %p
1706 %c2 = icmp eq i32 %a, 10
1707 store i1 %c2, ptr %p
1708 %c3 = icmp eq i32 %a, 11
1709 store i1 %c3, ptr %p
1710 %c4 = icmp eq i32 %a, 12
1711 store i1 %c4, ptr %p
1712 %c5 = icmp eq i32 %a, 13
1713 store i1 %c5, ptr %p
1720 define i1 @or_union_unknown_cond(i32 %a, i1 %c) {
1721 ; CHECK-LABEL: @or_union_unknown_cond(
1722 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 10
1723 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[C:%.*]]
1724 ; CHECK-NEXT: br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1726 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 10
1727 ; CHECK-NEXT: ret i1 [[CMP2]]
1729 ; CHECK-NEXT: ret i1 false
1731 %cmp1 = icmp eq i32 %a, 10
1732 %or = or i1 %cmp1, %c
1733 br i1 %or, label %guard, label %exit
1736 %cmp2 = icmp eq i32 %a, 10
1743 define void @and_union(i32 %a, ptr %p) {
1744 ; CHECK-LABEL: @and_union(
1745 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 10
1746 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[A]], 12
1747 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1748 ; CHECK-NEXT: br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1750 ; CHECK-NEXT: store i1 false, ptr [[P:%.*]], align 1
1751 ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[A]], 10
1752 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1753 ; CHECK-NEXT: [[C3:%.*]] = icmp eq i32 [[A]], 11
1754 ; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 1
1755 ; CHECK-NEXT: [[C4:%.*]] = icmp eq i32 [[A]], 12
1756 ; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
1757 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1758 ; CHECK-NEXT: br label [[EXIT]]
1760 ; CHECK-NEXT: ret void
1762 %cmp1 = icmp ne i32 %a, 10
1763 %cmp2 = icmp ne i32 %a, 12
1764 %and = and i1 %cmp1, %cmp2
1765 br i1 %and, label %exit, label %guard
1768 %c1 = icmp eq i32 %a, 9
1769 store i1 %c1, ptr %p
1770 %c2 = icmp eq i32 %a, 10
1771 store i1 %c2, ptr %p
1772 %c3 = icmp eq i32 %a, 11
1773 store i1 %c3, ptr %p
1774 %c4 = icmp eq i32 %a, 12
1775 store i1 %c4, ptr %p
1776 %c5 = icmp eq i32 %a, 13
1777 store i1 %c5, ptr %p
1784 define i1 @and_union_unknown_cond(i32 %a, i1 %c) {
1785 ; CHECK-LABEL: @and_union_unknown_cond(
1786 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 10
1787 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[C:%.*]]
1788 ; CHECK-NEXT: br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1790 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 10
1791 ; CHECK-NEXT: ret i1 [[CMP2]]
1793 ; CHECK-NEXT: ret i1 false
1795 %cmp1 = icmp ne i32 %a, 10
1796 %and = and i1 %cmp1, %c
1797 br i1 %and, label %exit, label %guard
1800 %cmp2 = icmp eq i32 %a, 10
1807 define void @select_assume(i32 %a, i32 %b, i1 %c, ptr %p) {
1808 ; CHECK-LABEL: @select_assume(
1809 ; CHECK-NEXT: [[C1:%.*]] = icmp ult i32 [[A:%.*]], 10
1810 ; CHECK-NEXT: call void @llvm.assume(i1 [[C1]])
1811 ; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[B:%.*]], 20
1812 ; CHECK-NEXT: call void @llvm.assume(i1 [[C2]])
1813 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C:%.*]], i32 [[A]], i32 [[B]]
1814 ; CHECK-NEXT: [[C3:%.*]] = icmp ult i32 [[S]], 19
1815 ; CHECK-NEXT: store i1 [[C3]], ptr [[P:%.*]], align 1
1816 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1817 ; CHECK-NEXT: ret void
1819 %c1 = icmp ult i32 %a, 10
1820 call void @llvm.assume(i1 %c1)
1821 %c2 = icmp ult i32 %b, 20
1822 call void @llvm.assume(i1 %c2)
1823 %s = select i1 %c, i32 %a, i32 %b
1824 %c3 = icmp ult i32 %s, 19
1825 store i1 %c3, ptr %p
1826 %c4 = icmp ult i32 %s, 20
1827 store i1 %c4, ptr %p
1831 define void @xor(i8 %a, ptr %p) {
1832 ; CHECK-LABEL: @xor(
1833 ; CHECK-NEXT: [[A_MASK:%.*]] = and i8 [[A:%.*]], 15
1834 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A_MASK]], -86
1835 ; CHECK-NEXT: store i1 true, ptr [[P:%.*]], align 1
1836 ; CHECK-NEXT: [[C2:%.*]] = icmp ugt i8 [[XOR]], -96
1837 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1838 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1839 ; CHECK-NEXT: [[C4:%.*]] = icmp ult i8 [[XOR]], -81
1840 ; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
1841 ; CHECK-NEXT: ret void
1843 %a.mask = and i8 %a, 15 ; 0b0000????
1844 %xor = xor i8 %a.mask, 170 ; ^ 0b10101010 == 0b1010????
1845 %c1 = icmp uge i8 %xor, 160
1846 store i1 %c1, ptr %p
1847 %c2 = icmp ugt i8 %xor, 160
1848 store i1 %c2, ptr %p
1849 %c3 = icmp ule i8 %xor, 175
1850 store i1 %c3, ptr %p
1851 %c4 = icmp ult i8 %xor, 175
1852 store i1 %c4, ptr %p
1856 define i1 @xor_neg_cond(i32 %a) {
1857 ; CHECK-LABEL: @xor_neg_cond(
1858 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 10
1859 ; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CMP1]], true
1860 ; CHECK-NEXT: br i1 [[XOR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1862 ; CHECK-NEXT: ret i1 true
1864 ; CHECK-NEXT: ret i1 false
1866 %cmp1 = icmp eq i32 %a, 10
1867 %xor = xor i1 %cmp1, true
1868 br i1 %xor, label %exit, label %guard
1871 %cmp2 = icmp eq i32 %a, 10
1878 define i1 @xor_approx(i32 %a) {
1879 ; CHECK-LABEL: @xor_approx(
1880 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 2
1881 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[A]], 5
1882 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[A]], 7
1883 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], 9
1884 ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP1]], [[CMP2]]
1885 ; CHECK-NEXT: [[AND2:%.*]] = and i1 [[CMP3]], [[CMP4]]
1886 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[AND1]], [[AND2]]
1887 ; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[OR]], true
1888 ; CHECK-NEXT: br i1 [[XOR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1890 ; CHECK-NEXT: [[CMP5:%.*]] = icmp eq i32 [[A]], 6
1891 ; CHECK-NEXT: ret i1 [[CMP5]]
1893 ; CHECK-NEXT: ret i1 false
1895 %cmp1 = icmp ugt i32 %a, 2
1896 %cmp2 = icmp ult i32 %a, 5
1897 %cmp3 = icmp ugt i32 %a, 7
1898 %cmp4 = icmp ult i32 %a, 9
1899 %and1 = and i1 %cmp1, %cmp2
1900 %and2 = and i1 %cmp3, %cmp4
1901 %or = or i1 %and1, %and2
1902 %xor = xor i1 %or, true
1903 br i1 %xor, label %exit, label %guard
1906 %cmp5 = icmp eq i32 %a, 6
1913 declare i32 @llvm.uadd.sat.i32(i32, i32)
1914 declare i32 @llvm.usub.sat.i32(i32, i32)
1915 declare i32 @llvm.sadd.sat.i32(i32, i32)
1916 declare i32 @llvm.ssub.sat.i32(i32, i32)
1917 declare void @llvm.assume(i1)