1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
5 define i32 @test1(i1 %C) {
6 ; CHECK-LABEL: define i32 @test1
7 ; CHECK-SAME: (i1 [[C:%.*]]) {
8 ; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[BODY:%.*]]
10 ; CHECK-NEXT: ret i32 11
12 ; CHECK-NEXT: ret i32 10
14 br i1 %C, label %exit, label %body
17 %A = select i1 %C, i32 10, i32 11
27 ; CHECK-LABEL: define i1 @test2() {
29 ; CHECK-NEXT: [[COND:%.*]] = tail call i1 @ext()
30 ; CHECK-NEXT: br i1 [[COND]], label [[BB1:%.*]], label [[BB2:%.*]]
32 ; CHECK-NEXT: [[COND2:%.*]] = tail call i1 @ext()
33 ; CHECK-NEXT: br i1 [[COND2]], label [[BB3:%.*]], label [[BB2]]
35 ; CHECK-NEXT: ret i1 false
37 ; CHECK-NEXT: [[RES:%.*]] = tail call i1 @ext()
38 ; CHECK-NEXT: ret i1 [[RES]]
41 %cond = tail call i1 @ext()
42 br i1 %cond, label %bb1, label %bb2
45 %cond2 = tail call i1 @ext()
46 br i1 %cond2, label %bb3, label %bb2
49 %cond_merge = phi i1 [ %cond, %entry ], [ false, %bb1 ]
53 %res = tail call i1 @ext()
58 @gv = internal constant i8 7
59 define i8 @test3(ptr %a) nounwind {
60 ; CHECK-LABEL: define i8 @test3
61 ; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
63 ; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[A]], @gv
64 ; CHECK-NEXT: br i1 [[COND]], label [[BB2:%.*]], label [[BB:%.*]]
66 ; CHECK-NEXT: ret i8 0
68 ; CHECK-NEXT: [[SHOULD_BE_CONST:%.*]] = load i8, ptr [[A]], align 1
69 ; CHECK-NEXT: ret i8 [[SHOULD_BE_CONST]]
72 %cond = icmp eq ptr %a, @gv
73 br i1 %cond, label %bb2, label %bb
79 %should_be_const = load i8, ptr %a
80 ret i8 %should_be_const
84 define i32 @test4(i32) {
85 ; CHECK-LABEL: define i32 @test4
86 ; CHECK-SAME: (i32 [[TMP0:%.*]]) {
87 ; CHECK-NEXT: EntryBlock:
88 ; CHECK-NEXT: [[DOTDEMORGAN:%.*]] = icmp sgt i32 [[TMP0]], 2
89 ; CHECK-NEXT: br i1 [[DOTDEMORGAN]], label [[GREATERTHANTWO:%.*]], label [[LESSTHANOREQUALTOTWO:%.*]]
90 ; CHECK: GreaterThanTwo:
91 ; CHECK-NEXT: br i1 false, label [[IMPOSSIBLE:%.*]], label [[NOTTWOANDGREATERTHANTWO:%.*]]
92 ; CHECK: NotTwoAndGreaterThanTwo:
93 ; CHECK-NEXT: ret i32 2
95 ; CHECK-NEXT: ret i32 1
96 ; CHECK: LessThanOrEqualToTwo:
97 ; CHECK-NEXT: ret i32 0
100 %.demorgan = icmp sgt i32 %0, 2
101 br i1 %.demorgan, label %GreaterThanTwo, label %LessThanOrEqualToTwo
105 br i1 %1, label %Impossible, label %NotTwoAndGreaterThanTwo
107 NotTwoAndGreaterThanTwo:
113 LessThanOrEqualToTwo:
118 define void @test5(ptr %x, ptr %y) {
119 ; CHECK-LABEL: define void @test5
120 ; CHECK-SAME: (ptr [[X:%.*]], ptr [[Y:%.*]]) {
122 ; CHECK-NEXT: [[PRE:%.*]] = icmp eq ptr [[X]], null
123 ; CHECK-NEXT: br i1 [[PRE]], label [[RETURN:%.*]], label [[LOOP:%.*]]
125 ; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[F:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY:%.*]] ]
126 ; CHECK-NEXT: [[F]] = tail call ptr @f(ptr [[PHI]])
127 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne ptr [[F]], [[Y]]
128 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], ptr [[F]], ptr null
129 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq ptr [[SEL]], null
130 ; CHECK-NEXT: br i1 [[CMP2]], label [[RETURN]], label [[LOOP]]
132 ; CHECK-NEXT: ret void
135 %pre = icmp eq ptr %x, null
136 br i1 %pre, label %return, label %loop
139 %phi = phi ptr [ %sel, %loop ], [ %x, %entry ]
140 %f = tail call ptr @f(ptr %phi)
141 %cmp1 = icmp ne ptr %f, %y
142 %sel = select i1 %cmp1, ptr %f, ptr null
143 %cmp2 = icmp eq ptr %sel, null
144 br i1 %cmp2, label %return, label %loop
150 ; "false" case for CorrelatedValuePropagation
151 define void @loop1(ptr %x, ptr %y) {
152 ; CHECK-LABEL: define void @loop1
153 ; CHECK-SAME: (ptr [[X:%.*]], ptr [[Y:%.*]]) {
155 ; CHECK-NEXT: br label [[LOOP:%.*]]
157 ; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[F:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY:%.*]] ]
158 ; CHECK-NEXT: [[F]] = tail call ptr @f(ptr [[PHI]])
159 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne ptr [[F]], [[Y]]
160 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], ptr [[F]], ptr null
161 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq ptr [[SEL]], null
162 ; CHECK-NEXT: br i1 [[CMP2]], label [[RETURN:%.*]], label [[LOOP]]
164 ; CHECK-NEXT: ret void
170 %phi = phi ptr [ %sel, %loop ], [ %x, %entry ]
171 %f = tail call ptr @f(ptr %phi)
172 %cmp1 = icmp ne ptr %f, %y
173 %sel = select i1 %cmp1, ptr %f, ptr null
174 %cmp2 = icmp eq ptr %sel, null
175 br i1 %cmp2, label %return, label %loop
181 ; "true" case for CorrelatedValuePropagation
182 define void @loop2(ptr %x, ptr %y) {
183 ; CHECK-LABEL: define void @loop2
184 ; CHECK-SAME: (ptr [[X:%.*]], ptr [[Y:%.*]]) {
186 ; CHECK-NEXT: br label [[LOOP:%.*]]
188 ; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[F:%.*]], [[LOOP]] ], [ [[X]], [[ENTRY:%.*]] ]
189 ; CHECK-NEXT: [[F]] = tail call ptr @f(ptr [[PHI]])
190 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq ptr [[F]], [[Y]]
191 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], ptr null, ptr [[F]]
192 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq ptr [[SEL]], null
193 ; CHECK-NEXT: br i1 [[CMP2]], label [[RETURN:%.*]], label [[LOOP]]
195 ; CHECK-NEXT: ret void
201 %phi = phi ptr [ %sel, %loop ], [ %x, %entry ]
202 %f = tail call ptr @f(ptr %phi)
203 %cmp1 = icmp eq ptr %f, %y
204 %sel = select i1 %cmp1, ptr null, ptr %f
205 %cmp2 = icmp eq ptr %sel, null
206 br i1 %cmp2, label %return, label %loop
212 define i32 @switch1(i32 %s) {
213 ; CHECK-LABEL: define i32 @switch1
214 ; CHECK-SAME: (i32 [[S:%.*]]) {
216 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[S]], 0
217 ; CHECK-NEXT: br i1 [[CMP]], label [[NEGATIVE:%.*]], label [[OUT:%.*]]
219 ; CHECK-NEXT: switch i32 [[S]], label [[OUT]] [
220 ; CHECK-NEXT: i32 -2, label [[NEXT:%.*]]
221 ; CHECK-NEXT: i32 -1, label [[NEXT]]
224 ; CHECK-NEXT: [[P:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ -1, [[NEGATIVE]] ]
225 ; CHECK-NEXT: ret i32 [[P]]
227 ; CHECK-NEXT: ret i32 0
230 %cmp = icmp slt i32 %s, 0
231 br i1 %cmp, label %negative, label %out
234 switch i32 %s, label %out [
244 %p = phi i32 [ 1, %entry ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ]
248 %q = phi i32 [ 0, %negative ], [ 0, %negative ]
252 define i32 @switch2(i32 %s) {
253 ; CHECK-LABEL: define i32 @switch2
254 ; CHECK-SAME: (i32 [[S:%.*]]) {
256 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[S]], 0
257 ; CHECK-NEXT: br i1 [[CMP]], label [[POSITIVE:%.*]], label [[OUT:%.*]]
259 ; CHECK-NEXT: br label [[OUT]]
261 ; CHECK-NEXT: [[P:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 1, [[POSITIVE]] ]
262 ; CHECK-NEXT: ret i32 [[P]]
264 ; CHECK-NEXT: ret i32 0
267 %cmp = icmp sgt i32 %s, 0
268 br i1 %cmp, label %positive, label %out
271 switch i32 %s, label %out [
278 %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
282 %q = phi i32 [ 0, %positive ], [ 0, %positive ]
286 define i32 @switch3(i32 %s) {
287 ; CHECK-LABEL: define i32 @switch3
288 ; CHECK-SAME: (i32 [[S:%.*]]) {
290 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[S]], 0
291 ; CHECK-NEXT: br i1 [[CMP]], label [[POSITIVE:%.*]], label [[OUT:%.*]]
293 ; CHECK-NEXT: br label [[OUT]]
295 ; CHECK-NEXT: [[P:%.*]] = phi i32 [ -1, [[ENTRY:%.*]] ], [ 1, [[POSITIVE]] ]
296 ; CHECK-NEXT: ret i32 [[P]]
298 ; CHECK-NEXT: ret i32 0
301 %cmp = icmp sgt i32 %s, 0
302 br i1 %cmp, label %positive, label %out
305 switch i32 %s, label %out [
312 %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
316 %q = phi i32 [ 0, %positive ], [ 0, %positive ]
320 define void @switch4(i32 %s) {
321 ; CHECK-LABEL: define void @switch4
322 ; CHECK-SAME: (i32 [[S:%.*]]) {
324 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[S]], 0
325 ; CHECK-NEXT: br i1 [[CMP]], label [[ZERO:%.*]], label [[OUT:%.*]]
327 ; CHECK-NEXT: br label [[NEXT:%.*]]
329 ; CHECK-NEXT: ret void
331 ; CHECK-NEXT: ret void
334 %cmp = icmp eq i32 %s, 0
335 br i1 %cmp, label %zero, label %out
338 switch i32 %s, label %out [
351 define void @switch_nonzero_zext(i8 %s) {
352 ; CHECK-LABEL: define void @switch_nonzero_zext
353 ; CHECK-SAME: (i8 [[S:%.*]]) {
355 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[S]], 0
356 ; CHECK-NEXT: br i1 [[CMP]], label [[SWITCH:%.*]], label [[EXIT:%.*]]
358 ; CHECK-NEXT: [[S_EXT:%.*]] = zext i8 [[S]] to i32
359 ; CHECK-NEXT: br label [[EXIT]]
361 ; CHECK-NEXT: ret void
362 ; CHECK: unreachable:
363 ; CHECK-NEXT: ret void
366 %cmp = icmp ne i8 %s, 0
367 br i1 %cmp, label %switch, label %exit
370 %s.ext = zext i8 %s to i32
371 switch i32 %s.ext, label %exit [
372 i32 0, label %unreachable
384 define void @switch_assume_nonzero(i32 %s) {
385 ; CHECK-LABEL: define void @switch_assume_nonzero
386 ; CHECK-SAME: (i32 [[S:%.*]]) {
388 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[S]], 0
389 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
390 ; CHECK-NEXT: br label [[EXIT:%.*]]
392 ; CHECK-NEXT: ret void
393 ; CHECK: unreachable:
394 ; CHECK-NEXT: ret void
397 %cmp = icmp ne i32 %s, 0
398 call void @llvm.assume(i1 %cmp)
399 switch i32 %s, label %exit [
400 i32 0, label %unreachable
412 define void @switch_nonzero_phi(i1 %cond) {
413 ; CHECK-LABEL: define void @switch_nonzero_phi
414 ; CHECK-SAME: (i1 [[COND:%.*]]) {
416 ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[ELSE:%.*]]
418 ; CHECK-NEXT: br label [[SWITCH:%.*]]
420 ; CHECK-NEXT: br label [[SWITCH]]
422 ; CHECK-NEXT: [[S:%.*]] = phi i32 [ 1, [[IF]] ], [ -1, [[ELSE]] ]
423 ; CHECK-NEXT: br label [[EXIT:%.*]]
425 ; CHECK-NEXT: ret void
426 ; CHECK: unreachable:
427 ; CHECK-NEXT: ret void
430 br i1 %cond, label %if, label %else
439 %s = phi i32 [ 1, %if ], [ -1, %else ]
440 switch i32 %s, label %exit [
441 i32 0, label %unreachable
453 define i32 @switch_range(i32 %cond) {
454 ; CHECK-LABEL: define i32 @switch_range
455 ; CHECK-SAME: (i32 [[COND:%.*]]) {
457 ; CHECK-NEXT: [[S:%.*]] = urem i32 [[COND]], 3
458 ; CHECK-NEXT: [[S1:%.*]] = add nuw nsw i32 [[S]], 1
459 ; CHECK-NEXT: switch i32 [[S1]], label [[DEFAULT_UNREACHABLE:%.*]] [
460 ; CHECK-NEXT: i32 1, label [[EXIT1:%.*]]
461 ; CHECK-NEXT: i32 2, label [[EXIT2:%.*]]
462 ; CHECK-NEXT: i32 3, label [[EXIT1]]
465 ; CHECK-NEXT: ret i32 1
467 ; CHECK-NEXT: ret i32 2
468 ; CHECK: default.unreachable:
469 ; CHECK-NEXT: unreachable
470 ; CHECK: unreachable:
471 ; CHECK-NEXT: ret i32 0
474 %s = urem i32 %cond, 3
476 switch i32 %s1, label %unreachable [
490 ; If the cases do not cover the entire range of the
491 ; switch condition, we should not change the default.
493 define i32 @switch_range_not_full(i32 %cond) {
494 ; CHECK-LABEL: define i32 @switch_range_not_full
495 ; CHECK-SAME: (i32 [[COND:%.*]]) {
497 ; CHECK-NEXT: [[S:%.*]] = urem i32 [[COND]], 3
498 ; CHECK-NEXT: [[S1:%.*]] = add nuw nsw i32 [[S]], 1
499 ; CHECK-NEXT: switch i32 [[S1]], label [[UNREACHABLE:%.*]] [
500 ; CHECK-NEXT: i32 1, label [[EXIT1:%.*]]
501 ; CHECK-NEXT: i32 3, label [[EXIT2:%.*]]
504 ; CHECK-NEXT: ret i32 1
506 ; CHECK-NEXT: ret i32 2
507 ; CHECK: unreachable:
508 ; CHECK-NEXT: ret i32 0
511 %s = urem i32 %cond, 3
513 switch i32 %s1, label %unreachable [
528 define i8 @switch_defaultdest_multipleuse(i8 %t0) {
529 ; CHECK-LABEL: define i8 @switch_defaultdest_multipleuse
530 ; CHECK-SAME: (i8 [[T0:%.*]]) {
532 ; CHECK-NEXT: [[O:%.*]] = or i8 [[T0]], 1
533 ; CHECK-NEXT: [[R:%.*]] = srem i8 1, [[O]]
534 ; CHECK-NEXT: br label [[EXIT:%.*]]
535 ; CHECK: default.unreachable:
536 ; CHECK-NEXT: unreachable
538 ; CHECK-NEXT: ret i8 0
543 switch i8 %r, label %exit [
552 define i1 @arg_attribute(ptr nonnull %a) {
553 ; CHECK-LABEL: define i1 @arg_attribute
554 ; CHECK-SAME: (ptr nonnull [[A:%.*]]) {
555 ; CHECK-NEXT: ret i1 false
557 %cmp = icmp eq ptr %a, null
561 declare nonnull ptr @return_nonnull()
562 define i1 @call_attribute() {
563 ; CHECK-LABEL: define i1 @call_attribute() {
564 ; CHECK-NEXT: [[A:%.*]] = call ptr @return_nonnull()
565 ; CHECK-NEXT: ret i1 false
567 %a = call ptr @return_nonnull()
568 %cmp = icmp eq ptr %a, null
572 define i1 @umin(i32 %a, i32 %b) {
573 ; CHECK-LABEL: define i1 @umin
574 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
576 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], 5
577 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
579 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B]], 20
580 ; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
582 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ult i32 [[A]], [[B]]
583 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
584 ; CHECK-NEXT: ret i1 false
586 ; CHECK-NEXT: ret i1 false
589 %cmp = icmp ult i32 %a, 5
590 br i1 %cmp, label %a_guard, label %out
593 %cmp2 = icmp ult i32 %b, 20
594 br i1 %cmp2, label %b_guard, label %out
597 %sel_cmp = icmp ult i32 %a, %b
598 %min = select i1 %sel_cmp, i32 %a, i32 %b
599 %res = icmp eq i32 %min, 7
605 define i1 @smin(i32 %a, i32 %b) {
606 ; CHECK-LABEL: define i1 @smin
607 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
609 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], 5
610 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
612 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B]], 20
613 ; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
615 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ule i32 [[A]], [[B]]
616 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
617 ; CHECK-NEXT: ret i1 false
619 ; CHECK-NEXT: ret i1 false
622 %cmp = icmp ult i32 %a, 5
623 br i1 %cmp, label %a_guard, label %out
626 %cmp2 = icmp ult i32 %b, 20
627 br i1 %cmp2, label %b_guard, label %out
630 %sel_cmp = icmp sle i32 %a, %b
631 %min = select i1 %sel_cmp, i32 %a, i32 %b
632 %res = icmp eq i32 %min, 7
638 define i1 @smax(i32 %a, i32 %b) {
639 ; CHECK-LABEL: define i1 @smax
640 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
642 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 5
643 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
645 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[B]], 20
646 ; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
648 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]]
649 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
650 ; CHECK-NEXT: ret i1 false
652 ; CHECK-NEXT: ret i1 false
655 %cmp = icmp sgt i32 %a, 5
656 br i1 %cmp, label %a_guard, label %out
659 %cmp2 = icmp sgt i32 %b, 20
660 br i1 %cmp2, label %b_guard, label %out
663 %sel_cmp = icmp sge i32 %a, %b
664 %max = select i1 %sel_cmp, i32 %a, i32 %b
665 %res = icmp eq i32 %max, 7
671 define i1 @umax(i32 %a, i32 %b) {
672 ; CHECK-LABEL: define i1 @umax
673 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
675 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 5
676 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
678 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[B]], 20
679 ; CHECK-NEXT: br i1 [[CMP2]], label [[B_GUARD:%.*]], label [[OUT]]
681 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]]
682 ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
683 ; CHECK-NEXT: ret i1 false
685 ; CHECK-NEXT: ret i1 false
688 %cmp = icmp sgt i32 %a, 5
689 br i1 %cmp, label %a_guard, label %out
692 %cmp2 = icmp sgt i32 %b, 20
693 br i1 %cmp2, label %b_guard, label %out
696 %sel_cmp = icmp uge i32 %a, %b
697 %max = select i1 %sel_cmp, i32 %a, i32 %b
698 %res = icmp eq i32 %max, 7
704 define i1 @umin_lhs_overdefined_rhs_const(i32 %a) {
705 ; CHECK-LABEL: define i1 @umin_lhs_overdefined_rhs_const
706 ; CHECK-SAME: (i32 [[A:%.*]]) {
707 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], 42
708 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 42
709 ; CHECK-NEXT: ret i1 true
711 %cmp = icmp ult i32 %a, 42
712 %sel = select i1 %cmp, i32 %a, i32 42
713 %cmp2 = icmp ule i32 %sel, 42
717 define i1 @umin_rhs_overdefined_lhs_const(i32 %a) {
718 ; CHECK-LABEL: define i1 @umin_rhs_overdefined_lhs_const
719 ; CHECK-SAME: (i32 [[A:%.*]]) {
720 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A]], 42
721 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 42, i32 [[A]]
722 ; CHECK-NEXT: ret i1 true
724 %cmp = icmp uge i32 %a, 42
725 %sel = select i1 %cmp, i32 42, i32 %a
726 %cmp2 = icmp ule i32 %sel, 42
730 define i1 @umin_lhs_overdefined_rhs_range(i32 %a, i32 %b) {
731 ; CHECK-LABEL: define i1 @umin_lhs_overdefined_rhs_range
732 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
733 ; CHECK-NEXT: [[ASSUME:%.*]] = icmp ult i32 [[B]], 42
734 ; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]])
735 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], [[B]]
736 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[B]]
737 ; CHECK-NEXT: ret i1 true
739 %assume = icmp ult i32 %b, 42
740 call void @llvm.assume(i1 %assume)
741 %cmp = icmp ult i32 %a, %b
742 %sel = select i1 %cmp, i32 %a, i32 %b
743 %cmp2 = icmp ult i32 %sel, 42
747 define i1 @umin_rhs_overdefined_lhs_range(i32 %a, i32 %b) {
748 ; CHECK-LABEL: define i1 @umin_rhs_overdefined_lhs_range
749 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
750 ; CHECK-NEXT: [[ASSUME:%.*]] = icmp ult i32 [[B]], 42
751 ; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]])
752 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A]], [[B]]
753 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[B]], i32 [[A]]
754 ; CHECK-NEXT: ret i1 true
756 %assume = icmp ult i32 %b, 42
757 call void @llvm.assume(i1 %assume)
758 %cmp = icmp uge i32 %a, %b
759 %sel = select i1 %cmp, i32 %b, i32 %a
760 %cmp2 = icmp ult i32 %sel, 42
764 define i1 @clamp_low1(i32 noundef %a) {
765 ; CHECK-LABEL: define i1 @clamp_low1
766 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
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 eq i32 [[A]], 5
772 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1
773 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
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 eq i32 %a, 5
784 %add = add i32 %a, -1
785 %sel = select i1 %sel_cmp, i32 5, i32 %add
786 %res = icmp eq i32 %sel, 4
792 define i1 @clamp_low2(i32 noundef %a) {
793 ; CHECK-LABEL: define i1 @clamp_low2
794 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
796 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], 5
797 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
799 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
800 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1
801 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
802 ; CHECK-NEXT: ret i1 false
804 ; CHECK-NEXT: ret i1 false
807 %cmp = icmp sge i32 %a, 5
808 br i1 %cmp, label %a_guard, label %out
811 %sel_cmp = icmp ne i32 %a, 5
812 %add = add i32 %a, -1
813 %sel = select i1 %sel_cmp, i32 %add, i32 5
814 %res = icmp eq i32 %sel, 4
820 define i1 @clamp_low3(i32 noundef %a) {
821 ; CHECK-LABEL: define i1 @clamp_low3
822 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
824 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], 5
825 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
827 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ugt i32 [[A]], 5
828 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1
829 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
830 ; CHECK-NEXT: ret i1 false
832 ; CHECK-NEXT: ret i1 false
835 %cmp = icmp sge i32 %a, 5
836 br i1 %cmp, label %a_guard, label %out
839 %sel_cmp = icmp sgt i32 %a, 5
840 %add = add i32 %a, -1
841 %sel = select i1 %sel_cmp, i32 %add, i32 5
842 %res = icmp eq i32 %sel, 4
848 define i1 @clamp_low4(i32 noundef %a) {
849 ; CHECK-LABEL: define i1 @clamp_low4
850 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
852 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], 5
853 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
855 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ule i32 [[A]], 5
856 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1
857 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
858 ; CHECK-NEXT: ret i1 false
860 ; CHECK-NEXT: ret i1 false
863 %cmp = icmp sge i32 %a, 5
864 br i1 %cmp, label %a_guard, label %out
867 %sel_cmp = icmp sle i32 %a, 5
868 %add = add i32 %a, -1
869 %sel = select i1 %sel_cmp, i32 5, i32 %add
870 %res = icmp eq i32 %sel, 4
876 define i1 @clamp_high1(i32 noundef %a) {
877 ; CHECK-LABEL: define i1 @clamp_high1
878 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
880 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 5
881 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
883 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5
884 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
885 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
886 ; CHECK-NEXT: ret i1 false
888 ; CHECK-NEXT: ret i1 false
891 %cmp = icmp sle i32 %a, 5
892 br i1 %cmp, label %a_guard, label %out
895 %sel_cmp = icmp eq i32 %a, 5
897 %sel = select i1 %sel_cmp, i32 5, i32 %add
898 %res = icmp eq i32 %sel, 6
904 define i1 @clamp_high1_or(i32 noundef %a) {
905 ; CHECK-LABEL: define i1 @clamp_high1_or
906 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
908 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 5
909 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
911 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5
912 ; CHECK-NEXT: [[ADD:%.*]] = or disjoint i32 [[A]], 1
913 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
914 ; CHECK-NEXT: ret i1 false
916 ; CHECK-NEXT: ret i1 false
919 %cmp = icmp sle i32 %a, 5
920 br i1 %cmp, label %a_guard, label %out
923 %sel_cmp = icmp eq i32 %a, 5
924 %add = or disjoint i32 %a, 1
925 %sel = select i1 %sel_cmp, i32 5, i32 %add
926 %res = icmp eq i32 %sel, 6
932 define i1 @clamp_high2(i32 noundef %a) {
933 ; CHECK-LABEL: define i1 @clamp_high2
934 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
936 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 5
937 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
939 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
940 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
941 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
942 ; CHECK-NEXT: ret i1 false
944 ; CHECK-NEXT: ret i1 false
947 %cmp = icmp sle i32 %a, 5
948 br i1 %cmp, label %a_guard, label %out
951 %sel_cmp = icmp ne i32 %a, 5
953 %sel = select i1 %sel_cmp, i32 %add, i32 5
954 %res = icmp eq i32 %sel, 6
961 define i1 @clamp_high2_or_disjoint(i32 noundef %a) {
962 ; CHECK-LABEL: define i1 @clamp_high2_or_disjoint
963 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
965 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 5
966 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
968 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
969 ; CHECK-NEXT: [[ADD:%.*]] = or disjoint i32 [[A]], 1
970 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
971 ; CHECK-NEXT: ret i1 false
973 ; CHECK-NEXT: ret i1 false
976 %cmp = icmp sle i32 %a, 5
977 br i1 %cmp, label %a_guard, label %out
980 %sel_cmp = icmp ne i32 %a, 5
981 %add = or disjoint i32 %a, 1
982 %sel = select i1 %sel_cmp, i32 %add, i32 5
983 %res = icmp eq i32 %sel, 6
990 define i1 @clamp_high3(i32 noundef %a) {
991 ; CHECK-LABEL: define i1 @clamp_high3
992 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
994 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 5
995 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
997 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp slt i32 [[A]], 5
998 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
999 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
1000 ; CHECK-NEXT: ret i1 false
1002 ; CHECK-NEXT: ret i1 false
1005 %cmp = icmp sle i32 %a, 5
1006 br i1 %cmp, label %a_guard, label %out
1009 %sel_cmp = icmp slt i32 %a, 5
1010 %add = add i32 %a, 1
1011 %sel = select i1 %sel_cmp, i32 %add, i32 5
1012 %res = icmp eq i32 %sel, 6
1018 define i1 @clamp_high4(i32 noundef %a) {
1019 ; CHECK-LABEL: define i1 @clamp_high4
1020 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
1021 ; CHECK-NEXT: entry:
1022 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 5
1023 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
1025 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sge i32 [[A]], 5
1026 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1
1027 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[ADD]]
1028 ; CHECK-NEXT: ret i1 false
1030 ; CHECK-NEXT: ret i1 false
1033 %cmp = icmp sle i32 %a, 5
1034 br i1 %cmp, label %a_guard, label %out
1037 %sel_cmp = icmp sge i32 %a, 5
1038 %add = add i32 %a, 1
1039 %sel = select i1 %sel_cmp, i32 5, i32 %add
1040 %res = icmp eq i32 %sel, 6
1046 ; Just showing arbitrary constants work, not really a clamp
1047 define i1 @not_clamp_high(i32 noundef %a) {
1048 ; CHECK-LABEL: define i1 @not_clamp_high
1049 ; CHECK-SAME: (i32 noundef [[A:%.*]]) {
1050 ; CHECK-NEXT: entry:
1051 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A]], 5
1052 ; CHECK-NEXT: br i1 [[CMP]], label [[A_GUARD:%.*]], label [[OUT:%.*]]
1054 ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5
1055 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 100
1056 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[ADD]], i32 5
1057 ; CHECK-NEXT: ret i1 false
1059 ; CHECK-NEXT: ret i1 false
1062 %cmp = icmp sle i32 %a, 5
1063 br i1 %cmp, label %a_guard, label %out
1066 %sel_cmp = icmp ne i32 %a, 5
1067 %add = add i32 %a, 100
1068 %sel = select i1 %sel_cmp, i32 %add, i32 5
1069 %res = icmp eq i32 %sel, 105
1075 define void @abs1(i32 %a, ptr %p) {
1076 ; CHECK-LABEL: define void @abs1
1077 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1078 ; CHECK-NEXT: entry:
1079 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], 10
1080 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1081 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1082 ; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1084 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]]
1085 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0
1086 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
1087 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1088 ; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[ABS]], 19
1089 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1090 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1091 ; CHECK-NEXT: [[C4:%.*]] = icmp uge i32 [[ABS]], 1
1092 ; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
1093 ; CHECK-NEXT: br label [[EXIT]]
1095 ; CHECK-NEXT: ret void
1098 %cmp1 = icmp slt i32 %a, 10
1099 %cmp2 = icmp sgt i32 %a, -20
1100 %and = and i1 %cmp1, %cmp2
1101 br i1 %and, label %guard, label %exit
1104 %sub = sub i32 0, %a
1105 %cmp = icmp slt i32 %a, 0
1106 %abs = select i1 %cmp, i32 %sub, i32 %a
1107 %c1 = icmp slt i32 %abs, 20
1108 store i1 %c1, ptr %p
1109 %c2 = icmp slt i32 %abs, 19
1110 store i1 %c2, ptr %p
1111 %c3 = icmp sge i32 %abs, 0
1112 store i1 %c3, ptr %p
1113 %c4 = icmp sge i32 %abs, 1
1114 store i1 %c4, ptr %p
1121 define void @abs2(i32 %a, ptr %p) {
1122 ; CHECK-LABEL: define void @abs2
1123 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1124 ; CHECK-NEXT: entry:
1125 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], 10
1126 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1127 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1128 ; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1130 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]]
1131 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], 0
1132 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]
1133 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1134 ; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[ABS]], 19
1135 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1136 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1137 ; CHECK-NEXT: [[C4:%.*]] = icmp uge i32 [[ABS]], 1
1138 ; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
1139 ; CHECK-NEXT: br label [[EXIT]]
1141 ; CHECK-NEXT: ret void
1144 %cmp1 = icmp slt i32 %a, 10
1145 %cmp2 = icmp sgt i32 %a, -20
1146 %and = and i1 %cmp1, %cmp2
1147 br i1 %and, label %guard, label %exit
1150 %sub = sub i32 0, %a
1151 %cmp = icmp sge i32 %a, 0
1152 %abs = select i1 %cmp, i32 %a, i32 %sub
1153 %c1 = icmp slt i32 %abs, 20
1154 store i1 %c1, ptr %p
1155 %c2 = icmp slt i32 %abs, 19
1156 store i1 %c2, ptr %p
1157 %c3 = icmp sge i32 %abs, 0
1158 store i1 %c3, ptr %p
1159 %c4 = icmp sge i32 %abs, 1
1160 store i1 %c4, ptr %p
1167 define void @nabs1(i32 %a, ptr %p) {
1168 ; CHECK-LABEL: define void @nabs1
1169 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1170 ; CHECK-NEXT: entry:
1171 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], 10
1172 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1173 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1174 ; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1176 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]]
1177 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 0
1178 ; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
1179 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1180 ; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[NABS]], -19
1181 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1182 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1183 ; CHECK-NEXT: [[C4:%.*]] = icmp sle i32 [[NABS]], -1
1184 ; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
1185 ; CHECK-NEXT: br label [[EXIT]]
1187 ; CHECK-NEXT: ret void
1190 %cmp1 = icmp slt i32 %a, 10
1191 %cmp2 = icmp sgt i32 %a, -20
1192 %and = and i1 %cmp1, %cmp2
1193 br i1 %and, label %guard, label %exit
1196 %sub = sub i32 0, %a
1197 %cmp = icmp sgt i32 %a, 0
1198 %nabs = select i1 %cmp, i32 %sub, i32 %a
1199 %c1 = icmp sgt i32 %nabs, -20
1200 store i1 %c1, ptr %p
1201 %c2 = icmp sgt i32 %nabs, -19
1202 store i1 %c2, ptr %p
1203 %c3 = icmp sle i32 %nabs, 0
1204 store i1 %c3, ptr %p
1205 %c4 = icmp sle i32 %nabs, -1
1206 store i1 %c4, ptr %p
1213 define void @nabs2(i32 %a, ptr %p) {
1214 ; CHECK-LABEL: define void @nabs2
1215 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1216 ; CHECK-NEXT: entry:
1217 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], 10
1218 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], -20
1219 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1220 ; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1222 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]]
1223 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0
1224 ; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]
1225 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1226 ; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[NABS]], -19
1227 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1228 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1229 ; CHECK-NEXT: [[C4:%.*]] = icmp sle i32 [[NABS]], -1
1230 ; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
1231 ; CHECK-NEXT: br label [[EXIT]]
1233 ; CHECK-NEXT: ret void
1236 %cmp1 = icmp slt i32 %a, 10
1237 %cmp2 = icmp sgt i32 %a, -20
1238 %and = and i1 %cmp1, %cmp2
1239 br i1 %and, label %guard, label %exit
1242 %sub = sub i32 0, %a
1243 %cmp = icmp slt i32 %a, 0
1244 %nabs = select i1 %cmp, i32 %a, i32 %sub
1245 %c1 = icmp sgt i32 %nabs, -20
1246 store i1 %c1, ptr %p
1247 %c2 = icmp sgt i32 %nabs, -19
1248 store i1 %c2, ptr %p
1249 %c3 = icmp sle i32 %nabs, 0
1250 store i1 %c3, ptr %p
1251 %c4 = icmp sle i32 %nabs, -1
1252 store i1 %c4, ptr %p
1259 define i1 @zext_unknown(i8 %a) {
1260 ; CHECK-LABEL: define i1 @zext_unknown
1261 ; CHECK-SAME: (i8 [[A:%.*]]) {
1262 ; CHECK-NEXT: entry:
1263 ; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A]] to i32
1264 ; CHECK-NEXT: ret i1 true
1267 %a32 = zext i8 %a to i32
1268 %cmp = icmp sle i32 %a32, 256
1272 define i1 @trunc_unknown(i32 %a) {
1273 ; CHECK-LABEL: define i1 @trunc_unknown
1274 ; CHECK-SAME: (i32 [[A:%.*]]) {
1275 ; CHECK-NEXT: entry:
1276 ; CHECK-NEXT: [[A8:%.*]] = trunc i32 [[A]] to i8
1277 ; CHECK-NEXT: [[A32:%.*]] = sext i8 [[A8]] to i32
1278 ; CHECK-NEXT: ret i1 true
1281 %a8 = trunc i32 %a to i8
1282 %a32 = sext i8 %a8 to i32
1283 %cmp = icmp sle i32 %a32, 128
1287 define void @trunc_icmp_ule(i32 %x, ptr %p) {
1288 ; CHECK-LABEL: define void @trunc_icmp_ule
1289 ; CHECK-SAME: (i32 [[X:%.*]], ptr [[P:%.*]]) {
1290 ; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X]] to i8
1291 ; CHECK-NEXT: [[C:%.*]] = icmp uge i8 [[T]], 5
1292 ; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1294 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1295 ; CHECK-NEXT: [[C2:%.*]] = icmp ugt i32 [[X]], 5
1296 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1297 ; CHECK-NEXT: [[C3:%.*]] = icmp ule i32 [[X]], 5
1298 ; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 1
1299 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1300 ; CHECK-NEXT: ret void
1302 ; CHECK-NEXT: [[C1_2:%.*]] = icmp uge i32 [[X]], 5
1303 ; CHECK-NEXT: store i1 [[C1_2]], ptr [[P]], align 1
1304 ; CHECK-NEXT: [[C2_2:%.*]] = icmp ugt i32 [[X]], 5
1305 ; CHECK-NEXT: store i1 [[C2_2]], ptr [[P]], align 1
1306 ; CHECK-NEXT: [[C3_2:%.*]] = icmp ule i32 [[X]], 5
1307 ; CHECK-NEXT: store i1 [[C3_2]], ptr [[P]], align 1
1308 ; CHECK-NEXT: [[C4_2:%.*]] = icmp ult i32 [[X]], 5
1309 ; CHECK-NEXT: store i1 [[C4_2]], ptr [[P]], align 1
1310 ; CHECK-NEXT: ret void
1312 %t = trunc i32 %x to i8
1313 %c = icmp uge i8 %t, 5
1314 br i1 %c, label %true, label %false
1317 %c1 = icmp uge i32 %x, 5
1318 store i1 %c1, ptr %p
1319 %c2 = icmp ugt i32 %x, 5
1320 store i1 %c2, ptr %p
1321 %c3 = icmp ule i32 %x, 5
1322 store i1 %c3, ptr %p
1323 %c4 = icmp ult i32 %x, 5
1324 store i1 %c4, ptr %p
1328 %c1.2 = icmp uge i32 %x, 5
1329 store i1 %c1.2, ptr %p
1330 %c2.2 = icmp ugt i32 %x, 5
1331 store i1 %c2.2, ptr %p
1332 %c3.2 = icmp ule i32 %x, 5
1333 store i1 %c3.2, ptr %p
1334 %c4.2 = icmp ult i32 %x, 5
1335 store i1 %c4.2, ptr %p
1339 define void @trunc_icmp_eq(i32 %x, ptr %p) {
1340 ; CHECK-LABEL: define void @trunc_icmp_eq
1341 ; CHECK-SAME: (i32 [[X:%.*]], ptr [[P:%.*]]) {
1342 ; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X]] to i8
1343 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[T]], 5
1344 ; CHECK-NEXT: br i1 [[C]], label [[TRUE:%.*]], label [[FALSE:%.*]]
1346 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1347 ; CHECK-NEXT: [[C2:%.*]] = icmp ugt i32 [[X]], 5
1348 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1349 ; CHECK-NEXT: [[C3:%.*]] = icmp ule i32 [[X]], 5
1350 ; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 1
1351 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1352 ; CHECK-NEXT: ret void
1354 ; CHECK-NEXT: [[C1_2:%.*]] = icmp uge i32 [[X]], 5
1355 ; CHECK-NEXT: store i1 [[C1_2]], ptr [[P]], align 1
1356 ; CHECK-NEXT: [[C2_2:%.*]] = icmp ugt i32 [[X]], 5
1357 ; CHECK-NEXT: store i1 [[C2_2]], ptr [[P]], align 1
1358 ; CHECK-NEXT: [[C3_2:%.*]] = icmp ule i32 [[X]], 5
1359 ; CHECK-NEXT: store i1 [[C3_2]], ptr [[P]], align 1
1360 ; CHECK-NEXT: [[C4_2:%.*]] = icmp ult i32 [[X]], 5
1361 ; CHECK-NEXT: store i1 [[C4_2]], ptr [[P]], align 1
1362 ; CHECK-NEXT: ret void
1364 %t = trunc i32 %x to i8
1365 %c = icmp eq i8 %t, 5
1366 br i1 %c, label %true, label %false
1369 %c1 = icmp uge i32 %x, 5
1370 store i1 %c1, ptr %p
1371 %c2 = icmp ugt i32 %x, 5
1372 store i1 %c2, ptr %p
1373 %c3 = icmp ule i32 %x, 5
1374 store i1 %c3, ptr %p
1375 %c4 = icmp ult i32 %x, 5
1376 store i1 %c4, ptr %p
1380 %c1.2 = icmp uge i32 %x, 5
1381 store i1 %c1.2, ptr %p
1382 %c2.2 = icmp ugt i32 %x, 5
1383 store i1 %c2.2, ptr %p
1384 %c3.2 = icmp ule i32 %x, 5
1385 store i1 %c3.2, ptr %p
1386 %c4.2 = icmp ult i32 %x, 5
1387 store i1 %c4.2, ptr %p
1391 ; TODO: missed optimization
1392 ; Make sure we exercise non-integer inputs to unary operators (i.e. crash check).
1393 define i1 @bitcast_unknown(float %a) {
1394 ; CHECK-LABEL: define i1 @bitcast_unknown
1395 ; CHECK-SAME: (float [[A:%.*]]) {
1396 ; CHECK-NEXT: entry:
1397 ; CHECK-NEXT: [[A32:%.*]] = bitcast float [[A]] to i32
1398 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A32]], 128
1399 ; CHECK-NEXT: ret i1 [[CMP]]
1402 %a32 = bitcast float %a to i32
1403 %cmp = icmp sle i32 %a32, 128
1407 define i1 @bitcast_unknown2(ptr %p) {
1408 ; CHECK-LABEL: define i1 @bitcast_unknown2
1409 ; CHECK-SAME: (ptr [[P:%.*]]) {
1410 ; CHECK-NEXT: entry:
1411 ; CHECK-NEXT: [[P64:%.*]] = ptrtoint ptr [[P]] to i64
1412 ; CHECK-NEXT: [[CMP:%.*]] = icmp sle i64 [[P64]], 128
1413 ; CHECK-NEXT: ret i1 [[CMP]]
1416 %p64 = ptrtoint ptr %p to i64
1417 %cmp = icmp sle i64 %p64, 128
1422 define i1 @and_unknown(i32 %a) {
1423 ; CHECK-LABEL: define i1 @and_unknown
1424 ; CHECK-SAME: (i32 [[A:%.*]]) {
1425 ; CHECK-NEXT: entry:
1426 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], 128
1427 ; CHECK-NEXT: ret i1 true
1430 %and = and i32 %a, 128
1431 %cmp = icmp sle i32 %and, 128
1435 define i1 @lshr_unknown(i32 %a) {
1436 ; CHECK-LABEL: define i1 @lshr_unknown
1437 ; CHECK-SAME: (i32 [[A:%.*]]) {
1438 ; CHECK-NEXT: entry:
1439 ; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[A]], 30
1440 ; CHECK-NEXT: ret i1 true
1443 %and = lshr i32 %a, 30
1444 %cmp = icmp sle i32 %and, 128
1448 define i1 @urem_unknown(i32 %a) {
1449 ; CHECK-LABEL: define i1 @urem_unknown
1450 ; CHECK-SAME: (i32 [[A:%.*]]) {
1451 ; CHECK-NEXT: entry:
1452 ; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[A]], 30
1453 ; CHECK-NEXT: ret i1 true
1456 %urem = urem i32 %a, 30
1457 %cmp = icmp ult i32 %urem, 30
1461 define i1 @srem_unknown(i32 %a) {
1462 ; CHECK-LABEL: define i1 @srem_unknown
1463 ; CHECK-SAME: (i32 [[A:%.*]]) {
1464 ; CHECK-NEXT: entry:
1465 ; CHECK-NEXT: [[SREM:%.*]] = srem i32 [[A]], 30
1466 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1468 ; CHECK-NEXT: ret i1 true
1470 ; CHECK-NEXT: ret i1 true
1473 %srem = srem i32 %a, 30
1474 %cmp1 = icmp slt i32 %srem, 30
1475 %cmp2 = icmp sgt i32 %srem, -30
1476 br i1 undef, label %exit1, label %exit2
1483 define i1 @sdiv_unknown(i32 %a) {
1484 ; CHECK-LABEL: define i1 @sdiv_unknown
1485 ; CHECK-SAME: (i32 [[A:%.*]]) {
1486 ; CHECK-NEXT: entry:
1487 ; CHECK-NEXT: [[SREM:%.*]] = sdiv i32 [[A]], 123
1488 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1490 ; CHECK-NEXT: ret i1 true
1492 ; CHECK-NEXT: ret i1 true
1495 %srem = sdiv i32 %a, 123
1496 %cmp1 = icmp slt i32 %srem, 17459217
1497 %cmp2 = icmp sgt i32 %srem, -17459217
1498 br i1 undef, label %exit1, label %exit2
1505 define i1 @uadd_sat_unknown(i32 %a) {
1506 ; CHECK-LABEL: define i1 @uadd_sat_unknown
1507 ; CHECK-SAME: (i32 [[A:%.*]]) {
1508 ; CHECK-NEXT: entry:
1509 ; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[A]], i32 100)
1510 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[VAL]], 100
1511 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1513 ; CHECK-NEXT: ret i1 true
1515 ; CHECK-NEXT: ret i1 [[CMP2]]
1518 %val = call i32 @llvm.uadd.sat.i32(i32 %a, i32 100)
1519 %cmp1 = icmp uge i32 %val, 100
1520 %cmp2 = icmp ugt i32 %val, 100
1521 br i1 undef, label %exit1, label %exit2
1528 define i1 @usub_sat_unknown(i32 %a) {
1529 ; CHECK-LABEL: define i1 @usub_sat_unknown
1530 ; CHECK-SAME: (i32 [[A:%.*]]) {
1531 ; CHECK-NEXT: entry:
1532 ; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A]], i32 100)
1533 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[VAL]], -101
1534 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1536 ; CHECK-NEXT: ret i1 true
1538 ; CHECK-NEXT: ret i1 [[CMP2]]
1541 %val = call i32 @llvm.usub.sat.i32(i32 %a, i32 100)
1542 %cmp1 = icmp ule i32 %val, 4294967195
1543 %cmp2 = icmp ult i32 %val, 4294967195
1544 br i1 undef, label %exit1, label %exit2
1551 define i1 @sadd_sat_unknown(i32 %a) {
1552 ; CHECK-LABEL: define i1 @sadd_sat_unknown
1553 ; CHECK-SAME: (i32 [[A:%.*]]) {
1554 ; CHECK-NEXT: entry:
1555 ; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A]], i32 100)
1556 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[VAL]], -2147483548
1557 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1559 ; CHECK-NEXT: ret i1 true
1561 ; CHECK-NEXT: ret i1 [[CMP2]]
1564 %val = call i32 @llvm.sadd.sat.i32(i32 %a, i32 100)
1565 %cmp1 = icmp sge i32 %val, -2147483548
1566 %cmp2 = icmp sgt i32 %val, -2147483548
1567 br i1 undef, label %exit1, label %exit2
1574 define i1 @ssub_sat_unknown(i32 %a) {
1575 ; CHECK-LABEL: define i1 @ssub_sat_unknown
1576 ; CHECK-SAME: (i32 [[A:%.*]]) {
1577 ; CHECK-NEXT: entry:
1578 ; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A]], i32 100)
1579 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[VAL]], 2147483547
1580 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]]
1582 ; CHECK-NEXT: ret i1 true
1584 ; CHECK-NEXT: ret i1 [[CMP2]]
1587 %val = call i32 @llvm.ssub.sat.i32(i32 %a, i32 100)
1588 %cmp1 = icmp sle i32 %val, 2147483547
1589 %cmp2 = icmp slt i32 %val, 2147483547
1590 br i1 undef, label %exit1, label %exit2
1597 define void @select_and(i32 %a, ptr %p) {
1598 ; CHECK-LABEL: define void @select_and
1599 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1600 ; CHECK-NEXT: entry:
1601 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], -10
1602 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1603 ; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 false
1604 ; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1606 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1607 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1608 ; CHECK-NEXT: br label [[EXIT]]
1610 ; CHECK-NEXT: ret void
1613 %cmp1 = icmp sgt i32 %a, -10
1614 %cmp2 = icmp slt i32 %a, 10
1615 %and = select i1 %cmp1, i1 %cmp2, i1 false
1616 br i1 %and, label %guard, label %exit
1619 %c1 = icmp sgt i32 %a, 20
1620 store i1 %c1, ptr %p
1621 %c2 = icmp slt i32 %a, -20
1622 store i1 %c2, ptr %p
1629 define void @select_and_wrong_const(i32 %a, ptr %p) {
1630 ; CHECK-LABEL: define void @select_and_wrong_const
1631 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1632 ; CHECK-NEXT: entry:
1633 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], -10
1634 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1635 ; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true
1636 ; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1638 ; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20
1639 ; CHECK-NEXT: store i1 [[C1]], ptr [[P]], align 1
1640 ; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20
1641 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1642 ; CHECK-NEXT: br label [[EXIT]]
1644 ; CHECK-NEXT: ret void
1647 %cmp1 = icmp sgt i32 %a, -10
1648 %cmp2 = icmp slt i32 %a, 10
1649 %and = select i1 %cmp1, i1 %cmp2, i1 true
1650 br i1 %and, label %guard, label %exit
1653 %c1 = icmp sgt i32 %a, 20
1654 store i1 %c1, ptr %p
1655 %c2 = icmp slt i32 %a, -20
1656 store i1 %c2, ptr %p
1663 define void @select_and_wrong_operand(i32 %a, ptr %p) {
1664 ; CHECK-LABEL: define void @select_and_wrong_operand
1665 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1666 ; CHECK-NEXT: entry:
1667 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A]], -10
1668 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], 10
1669 ; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]
1670 ; CHECK-NEXT: br i1 [[AND]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1672 ; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20
1673 ; CHECK-NEXT: store i1 [[C1]], ptr [[P]], align 1
1674 ; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20
1675 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1676 ; CHECK-NEXT: br label [[EXIT]]
1678 ; CHECK-NEXT: ret void
1681 %cmp1 = icmp sgt i32 %a, -10
1682 %cmp2 = icmp slt i32 %a, 10
1683 %and = select i1 %cmp1, i1 false, i1 %cmp2
1684 br i1 %and, label %guard, label %exit
1687 %c1 = icmp sgt i32 %a, 20
1688 store i1 %c1, ptr %p
1689 %c2 = icmp slt i32 %a, -20
1690 store i1 %c2, ptr %p
1697 define void @select_or(i32 %a, ptr %p) {
1698 ; CHECK-LABEL: define void @select_or
1699 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1700 ; CHECK-NEXT: entry:
1701 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], -10
1702 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1703 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP2]]
1704 ; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1706 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1707 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1708 ; CHECK-NEXT: br label [[EXIT]]
1710 ; CHECK-NEXT: ret void
1713 %cmp1 = icmp slt i32 %a, -10
1714 %cmp2 = icmp sgt i32 %a, 10
1715 %or = select i1 %cmp1, i1 true, i1 %cmp2
1716 br i1 %or, label %exit, label %guard
1719 %c1 = icmp sgt i32 %a, 20
1720 store i1 %c1, ptr %p
1721 %c2 = icmp slt i32 %a, -20
1722 store i1 %c2, ptr %p
1729 define void @select_or_wrong_const(i32 %a, ptr %p) {
1730 ; CHECK-LABEL: define void @select_or_wrong_const
1731 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1732 ; CHECK-NEXT: entry:
1733 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], -10
1734 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1735 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 false, i1 [[CMP2]]
1736 ; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1738 ; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20
1739 ; CHECK-NEXT: store i1 [[C1]], ptr [[P]], align 1
1740 ; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20
1741 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1742 ; CHECK-NEXT: br label [[EXIT]]
1744 ; CHECK-NEXT: ret void
1747 %cmp1 = icmp slt i32 %a, -10
1748 %cmp2 = icmp sgt i32 %a, 10
1749 %or = select i1 %cmp1, i1 false, i1 %cmp2
1750 br i1 %or, label %exit, label %guard
1753 %c1 = icmp sgt i32 %a, 20
1754 store i1 %c1, ptr %p
1755 %c2 = icmp slt i32 %a, -20
1756 store i1 %c2, ptr %p
1763 define void @select_or_wrong_operand(i32 %a, ptr %p) {
1764 ; CHECK-LABEL: define void @select_or_wrong_operand
1765 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1766 ; CHECK-NEXT: entry:
1767 ; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[A]], -10
1768 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[A]], 10
1769 ; CHECK-NEXT: [[OR:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 true
1770 ; CHECK-NEXT: br i1 [[OR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1772 ; CHECK-NEXT: [[C1:%.*]] = icmp sgt i32 [[A]], 20
1773 ; CHECK-NEXT: store i1 [[C1]], ptr [[P]], align 1
1774 ; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[A]], -20
1775 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1776 ; CHECK-NEXT: br label [[EXIT]]
1778 ; CHECK-NEXT: ret void
1781 %cmp1 = icmp slt i32 %a, -10
1782 %cmp2 = icmp sgt i32 %a, 10
1783 %or = select i1 %cmp1, i1 %cmp2, i1 true
1784 br i1 %or, label %exit, label %guard
1787 %c1 = icmp sgt i32 %a, 20
1788 store i1 %c1, ptr %p
1789 %c2 = icmp slt i32 %a, -20
1790 store i1 %c2, ptr %p
1797 define void @or_union(i32 %a, ptr %p) {
1798 ; CHECK-LABEL: define void @or_union
1799 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1800 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A]], 10
1801 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 12
1802 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
1803 ; CHECK-NEXT: br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1805 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1806 ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[A]], 10
1807 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1808 ; CHECK-NEXT: [[C3:%.*]] = icmp eq i32 [[A]], 11
1809 ; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 1
1810 ; CHECK-NEXT: [[C4:%.*]] = icmp eq i32 [[A]], 12
1811 ; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
1812 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1813 ; CHECK-NEXT: br label [[EXIT]]
1815 ; CHECK-NEXT: ret void
1817 %cmp1 = icmp eq i32 %a, 10
1818 %cmp2 = icmp eq i32 %a, 12
1819 %or = or i1 %cmp1, %cmp2
1820 br i1 %or, label %guard, label %exit
1823 %c1 = icmp eq i32 %a, 9
1824 store i1 %c1, ptr %p
1825 %c2 = icmp eq i32 %a, 10
1826 store i1 %c2, ptr %p
1827 %c3 = icmp eq i32 %a, 11
1828 store i1 %c3, ptr %p
1829 %c4 = icmp eq i32 %a, 12
1830 store i1 %c4, ptr %p
1831 %c5 = icmp eq i32 %a, 13
1832 store i1 %c5, ptr %p
1839 define i1 @or_union_unknown_cond(i32 %a, i1 %c) {
1840 ; CHECK-LABEL: define i1 @or_union_unknown_cond
1841 ; CHECK-SAME: (i32 [[A:%.*]], i1 [[C:%.*]]) {
1842 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A]], 10
1843 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[C]]
1844 ; CHECK-NEXT: br i1 [[OR]], label [[GUARD:%.*]], label [[EXIT:%.*]]
1846 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 10
1847 ; CHECK-NEXT: ret i1 [[CMP2]]
1849 ; CHECK-NEXT: ret i1 false
1851 %cmp1 = icmp eq i32 %a, 10
1852 %or = or i1 %cmp1, %c
1853 br i1 %or, label %guard, label %exit
1856 %cmp2 = icmp eq i32 %a, 10
1863 define void @and_union(i32 %a, ptr %p) {
1864 ; CHECK-LABEL: define void @and_union
1865 ; CHECK-SAME: (i32 [[A:%.*]], ptr [[P:%.*]]) {
1866 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A]], 10
1867 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[A]], 12
1868 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
1869 ; CHECK-NEXT: br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1871 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1872 ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[A]], 10
1873 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1874 ; CHECK-NEXT: [[C3:%.*]] = icmp eq i32 [[A]], 11
1875 ; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 1
1876 ; CHECK-NEXT: [[C4:%.*]] = icmp eq i32 [[A]], 12
1877 ; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
1878 ; CHECK-NEXT: store i1 false, ptr [[P]], align 1
1879 ; CHECK-NEXT: br label [[EXIT]]
1881 ; CHECK-NEXT: ret void
1883 %cmp1 = icmp ne i32 %a, 10
1884 %cmp2 = icmp ne i32 %a, 12
1885 %and = and i1 %cmp1, %cmp2
1886 br i1 %and, label %exit, label %guard
1889 %c1 = icmp eq i32 %a, 9
1890 store i1 %c1, ptr %p
1891 %c2 = icmp eq i32 %a, 10
1892 store i1 %c2, ptr %p
1893 %c3 = icmp eq i32 %a, 11
1894 store i1 %c3, ptr %p
1895 %c4 = icmp eq i32 %a, 12
1896 store i1 %c4, ptr %p
1897 %c5 = icmp eq i32 %a, 13
1898 store i1 %c5, ptr %p
1905 define i1 @and_union_unknown_cond(i32 %a, i1 %c) {
1906 ; CHECK-LABEL: define i1 @and_union_unknown_cond
1907 ; CHECK-SAME: (i32 [[A:%.*]], i1 [[C:%.*]]) {
1908 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A]], 10
1909 ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[C]]
1910 ; CHECK-NEXT: br i1 [[AND]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1912 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[A]], 10
1913 ; CHECK-NEXT: ret i1 [[CMP2]]
1915 ; CHECK-NEXT: ret i1 false
1917 %cmp1 = icmp ne i32 %a, 10
1918 %and = and i1 %cmp1, %c
1919 br i1 %and, label %exit, label %guard
1922 %cmp2 = icmp eq i32 %a, 10
1929 define void @select_assume(i32 %a, i32 %b, i1 %c, ptr %p) {
1930 ; CHECK-LABEL: define void @select_assume
1931 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i1 [[C:%.*]], ptr [[P:%.*]]) {
1932 ; CHECK-NEXT: [[C1:%.*]] = icmp ult i32 [[A]], 10
1933 ; CHECK-NEXT: call void @llvm.assume(i1 [[C1]])
1934 ; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[B]], 20
1935 ; CHECK-NEXT: call void @llvm.assume(i1 [[C2]])
1936 ; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 [[A]], i32 [[B]]
1937 ; CHECK-NEXT: [[C3:%.*]] = icmp ult i32 [[S]], 19
1938 ; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 1
1939 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1940 ; CHECK-NEXT: ret void
1942 %c1 = icmp ult i32 %a, 10
1943 call void @llvm.assume(i1 %c1)
1944 %c2 = icmp ult i32 %b, 20
1945 call void @llvm.assume(i1 %c2)
1946 %s = select i1 %c, i32 %a, i32 %b
1947 %c3 = icmp ult i32 %s, 19
1948 store i1 %c3, ptr %p
1949 %c4 = icmp ult i32 %s, 20
1950 store i1 %c4, ptr %p
1954 define void @xor(i8 %a, ptr %p) {
1955 ; CHECK-LABEL: define void @xor
1956 ; CHECK-SAME: (i8 [[A:%.*]], ptr [[P:%.*]]) {
1957 ; CHECK-NEXT: [[A_MASK:%.*]] = and i8 [[A]], 15
1958 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A_MASK]], -86
1959 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1960 ; CHECK-NEXT: [[C2:%.*]] = icmp ugt i8 [[XOR]], -96
1961 ; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
1962 ; CHECK-NEXT: store i1 true, ptr [[P]], align 1
1963 ; CHECK-NEXT: [[C4:%.*]] = icmp ult i8 [[XOR]], -81
1964 ; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
1965 ; CHECK-NEXT: ret void
1967 %a.mask = and i8 %a, 15 ; 0b0000????
1968 %xor = xor i8 %a.mask, 170 ; ^ 0b10101010 == 0b1010????
1969 %c1 = icmp uge i8 %xor, 160
1970 store i1 %c1, ptr %p
1971 %c2 = icmp ugt i8 %xor, 160
1972 store i1 %c2, ptr %p
1973 %c3 = icmp ule i8 %xor, 175
1974 store i1 %c3, ptr %p
1975 %c4 = icmp ult i8 %xor, 175
1976 store i1 %c4, ptr %p
1980 define i1 @xor_neg_cond(i32 %a) {
1981 ; CHECK-LABEL: define i1 @xor_neg_cond
1982 ; CHECK-SAME: (i32 [[A:%.*]]) {
1983 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A]], 10
1984 ; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[CMP1]], true
1985 ; CHECK-NEXT: br i1 [[XOR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
1987 ; CHECK-NEXT: ret i1 true
1989 ; CHECK-NEXT: ret i1 false
1991 %cmp1 = icmp eq i32 %a, 10
1992 %xor = xor i1 %cmp1, true
1993 br i1 %xor, label %exit, label %guard
1996 %cmp2 = icmp eq i32 %a, 10
2003 define i1 @xor_approx(i32 %a) {
2004 ; CHECK-LABEL: define i1 @xor_approx
2005 ; CHECK-SAME: (i32 [[A:%.*]]) {
2006 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[A]], 2
2007 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[A]], 5
2008 ; CHECK-NEXT: [[CMP3:%.*]] = icmp ugt i32 [[A]], 7
2009 ; CHECK-NEXT: [[CMP4:%.*]] = icmp ult i32 [[A]], 9
2010 ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[CMP1]], [[CMP2]]
2011 ; CHECK-NEXT: [[AND2:%.*]] = and i1 [[CMP3]], [[CMP4]]
2012 ; CHECK-NEXT: [[OR:%.*]] = or i1 [[AND1]], [[AND2]]
2013 ; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[OR]], true
2014 ; CHECK-NEXT: br i1 [[XOR]], label [[EXIT:%.*]], label [[GUARD:%.*]]
2016 ; CHECK-NEXT: [[CMP5:%.*]] = icmp eq i32 [[A]], 6
2017 ; CHECK-NEXT: ret i1 [[CMP5]]
2019 ; CHECK-NEXT: ret i1 false
2021 %cmp1 = icmp ugt i32 %a, 2
2022 %cmp2 = icmp ult i32 %a, 5
2023 %cmp3 = icmp ugt i32 %a, 7
2024 %cmp4 = icmp ult i32 %a, 9
2025 %and1 = and i1 %cmp1, %cmp2
2026 %and2 = and i1 %cmp3, %cmp4
2027 %or = or i1 %and1, %and2
2028 %xor = xor i1 %or, true
2029 br i1 %xor, label %exit, label %guard
2032 %cmp5 = icmp eq i32 %a, 6
2039 define i1 @binop_eval_order(i32 %x) {
2040 ; CHECK-LABEL: define i1 @binop_eval_order
2041 ; CHECK-SAME: (i32 [[X:%.*]]) {
2042 ; CHECK-NEXT: [[A:%.*]] = add nuw nsw i32 [[X]], 1
2043 ; CHECK-NEXT: [[B:%.*]] = add nuw nsw i32 [[A]], 1
2044 ; CHECK-NEXT: [[C:%.*]] = add nuw nsw i32 [[A]], [[B]]
2045 ; CHECK-NEXT: ret i1 true
2047 %a = add nuw nsw i32 %x, 1
2048 %b = add nuw nsw i32 %a, 1
2049 %c = add nuw nsw i32 %a, %b
2050 %d = icmp ugt i32 %c, 2
2054 define range(i32 0, 1024) i32 @range_larger(i8 %x) {
2055 ; CHECK-LABEL: define range(i32 0, 1024) i32 @range_larger
2056 ; CHECK-SAME: (i8 [[X:%.*]]) {
2057 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X]] to i32
2058 ; CHECK-NEXT: ret i32 [[ZEXT]]
2060 %zext = zext i8 %x to i32
2064 define range(i32 0, 128) i32 @range_smaller(i8 %x) {
2065 ; CHECK-LABEL: define range(i32 0, 128) i32 @range_smaller
2066 ; CHECK-SAME: (i8 [[X:%.*]]) {
2067 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X]] to i32
2068 ; CHECK-NEXT: ret i32 [[ZEXT]]
2070 %zext = zext i8 %x to i32
2074 define range(i32 128, 512) i32 @range_intersect(i8 %x) {
2075 ; CHECK-LABEL: define range(i32 128, 512) i32 @range_intersect
2076 ; CHECK-SAME: (i8 [[X:%.*]]) {
2077 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X]] to i32
2078 ; CHECK-NEXT: ret i32 [[ZEXT]]
2080 %zext = zext i8 %x to i32
2084 define range(i32 512, 1024) i32 @range_non_overlapping(i8 %x) {
2085 ; CHECK-LABEL: define range(i32 512, 1024) i32 @range_non_overlapping
2086 ; CHECK-SAME: (i8 [[X:%.*]]) {
2087 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X]] to i32
2088 ; CHECK-NEXT: ret i32 [[ZEXT]]
2090 %zext = zext i8 %x to i32
2094 declare i32 @llvm.uadd.sat.i32(i32, i32)
2095 declare i32 @llvm.usub.sat.i32(i32, i32)
2096 declare i32 @llvm.sadd.sat.i32(i32, i32)
2097 declare i32 @llvm.ssub.sat.i32(i32, i32)
2098 declare void @llvm.assume(i1)