Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / ucmp.ll
blob7210455094baacb786486954ed86be7a1ac773cf
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare void @use(i8 %value)
6 define i1 @ucmp_eq_0(i32 %x, i32 %y) {
7 ; CHECK-LABEL: define i1 @ucmp_eq_0(
8 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
9 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[X]], [[Y]]
10 ; CHECK-NEXT:    ret i1 [[TMP2]]
12   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
13   %2 = icmp eq i8 %1, 0
14   ret i1 %2
17 define i1 @ucmp_ne_0(i32 %x, i32 %y) {
18 ; CHECK-LABEL: define i1 @ucmp_ne_0(
19 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
20 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[X]], [[Y]]
21 ; CHECK-NEXT:    ret i1 [[TMP2]]
23   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
24   %2 = icmp ne i8 %1, 0
25   ret i1 %2
28 define i1 @ucmp_eq_1(i32 %x, i32 %y) {
29 ; CHECK-LABEL: define i1 @ucmp_eq_1(
30 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
31 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i32 [[X]], [[Y]]
32 ; CHECK-NEXT:    ret i1 [[TMP2]]
34   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
35   %2 = icmp eq i8 %1, 1
36   ret i1 %2
39 define i1 @ucmp_ne_1(i32 %x, i32 %y) {
40 ; CHECK-LABEL: define i1 @ucmp_ne_1(
41 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
42 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ule i32 [[X]], [[Y]]
43 ; CHECK-NEXT:    ret i1 [[TMP2]]
45   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
46   %2 = icmp ne i8 %1, 1
47   ret i1 %2
50 define i1 @ucmp_eq_negative_1(i32 %x, i32 %y) {
51 ; CHECK-LABEL: define i1 @ucmp_eq_negative_1(
52 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
53 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[X]], [[Y]]
54 ; CHECK-NEXT:    ret i1 [[TMP2]]
56   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
57   %2 = icmp eq i8 %1, -1
58   ret i1 %2
61 define i1 @ucmp_ne_negative_1(i32 %x, i32 %y) {
62 ; CHECK-LABEL: define i1 @ucmp_ne_negative_1(
63 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
64 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i32 [[X]], [[Y]]
65 ; CHECK-NEXT:    ret i1 [[TMP2]]
67   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
68   %2 = icmp ne i8 %1, -1
69   ret i1 %2
72 define i1 @ucmp_sgt_0(i32 %x, i32 %y) {
73 ; CHECK-LABEL: define i1 @ucmp_sgt_0(
74 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
75 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i32 [[X]], [[Y]]
76 ; CHECK-NEXT:    ret i1 [[TMP2]]
78   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
79   %2 = icmp sgt i8 %1, 0
80   ret i1 %2
83 define i1 @ucmp_sgt_neg_1(i32 %x, i32 %y) {
84 ; CHECK-LABEL: define i1 @ucmp_sgt_neg_1(
85 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
86 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i32 [[X]], [[Y]]
87 ; CHECK-NEXT:    ret i1 [[TMP2]]
89   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
90   %2 = icmp sgt i8 %1, -1
91   ret i1 %2
94 define i1 @ucmp_sge_0(i32 %x, i32 %y) {
95 ; CHECK-LABEL: define i1 @ucmp_sge_0(
96 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
97 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp uge i32 [[X]], [[Y]]
98 ; CHECK-NEXT:    ret i1 [[TMP2]]
100   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
101   %2 = icmp sge i8 %1, 0
102   ret i1 %2
105 define i1 @ucmp_sge_1(i32 %x, i32 %y) {
106 ; CHECK-LABEL: define i1 @ucmp_sge_1(
107 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
108 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i32 [[X]], [[Y]]
109 ; CHECK-NEXT:    ret i1 [[TMP2]]
111   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
112   %2 = icmp sge i8 %1, 1
113   ret i1 %2
116 define i1 @ucmp_slt_0(i32 %x, i32 %y) {
117 ; CHECK-LABEL: define i1 @ucmp_slt_0(
118 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
119 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[X]], [[Y]]
120 ; CHECK-NEXT:    ret i1 [[TMP2]]
122   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
123   %2 = icmp slt i8 %1, 0
124   ret i1 %2
127 define i1 @ucmp_slt_1(i32 %x, i32 %y) {
128 ; CHECK-LABEL: define i1 @ucmp_slt_1(
129 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
130 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ule i32 [[X]], [[Y]]
131 ; CHECK-NEXT:    ret i1 [[TMP2]]
133   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
134   %2 = icmp slt i8 %1, 1
135   ret i1 %2
138 define i1 @ucmp_sle_0(i32 %x, i32 %y) {
139 ; CHECK-LABEL: define i1 @ucmp_sle_0(
140 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
141 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ule i32 [[X]], [[Y]]
142 ; CHECK-NEXT:    ret i1 [[TMP2]]
144   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
145   %2 = icmp sle i8 %1, 0
146   ret i1 %2
149 define i1 @ucmp_sle_neg_1(i32 %x, i32 %y) {
150 ; CHECK-LABEL: define i1 @ucmp_sle_neg_1(
151 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
152 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[X]], [[Y]]
153 ; CHECK-NEXT:    ret i1 [[TMP2]]
155   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
156   %2 = icmp sle i8 %1, -1
157   ret i1 %2
160 ; ========== Fold -ucmp(x, y) => ucmp(y, x) ==========
161 define i8 @ucmp_negated(i32 %x, i32 %y) {
162 ; CHECK-LABEL: define i8 @ucmp_negated(
163 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
164 ; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[Y]], i32 [[X]])
165 ; CHECK-NEXT:    ret i8 [[TMP2]]
167   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
168   %2 = sub i8 0, %1
169   ret i8 %2
172 ; Negative test: do not fold if the original ucmp result is already used
173 define i8 @ucmp_negated_multiuse(i32 %x, i32 %y) {
174 ; CHECK-LABEL: define i8 @ucmp_negated_multiuse(
175 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
176 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
177 ; CHECK-NEXT:    call void @use(i8 [[TMP1]])
178 ; CHECK-NEXT:    [[TMP2:%.*]] = sub nsw i8 0, [[TMP1]]
179 ; CHECK-NEXT:    ret i8 [[TMP2]]
181   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
182   call void @use(i8 %1)
183   %2 = sub i8 0, %1
184   ret i8 %2