Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstSimplify / uscmp.ll
blob47720060acb52889e61958b03d8bf810a80752de
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
4 define i8 @scmp_lt() {
5 ; CHECK-LABEL: define i8 @scmp_lt() {
6 ; CHECK-NEXT:    ret i8 -1
8   %1 = call i8 @llvm.scmp(i32 -7, i32 3)
9   ret i8 %1
12 define i8 @scmp_eq() {
13 ; CHECK-LABEL: define i8 @scmp_eq() {
14 ; CHECK-NEXT:    ret i8 0
16   %1 = call i8 @llvm.scmp(i32 2, i32 2)
17   ret i8 %1
20 define i8 @scmp_gt() {
21 ; CHECK-LABEL: define i8 @scmp_gt() {
22 ; CHECK-NEXT:    ret i8 1
24   %1 = call i8 @llvm.scmp(i32 2, i32 -7)
25   ret i8 %1
28 define i8 @ucmp_lt() {
29 ; CHECK-LABEL: define i8 @ucmp_lt() {
30 ; CHECK-NEXT:    ret i8 -1
32   %1 = call i8 @llvm.ucmp(i32 7, i32 12)
33   ret i8 %1
36 define i2 @ucmp_eq() {
37 ; CHECK-LABEL: define i2 @ucmp_eq() {
38 ; CHECK-NEXT:    ret i2 0
40   %1 = call i2 @llvm.ucmp(i32 12, i32 12)
41   ret i2 %1
44 define i100 @ucmp_gt() {
45 ; CHECK-LABEL: define i100 @ucmp_gt() {
46 ; CHECK-NEXT:    ret i100 1
48   %1 = call i100 @llvm.ucmp(i32 7, i32 3)
49   ret i100 %1
52 define i8 @ucmp_poison() {
53 ; CHECK-LABEL: define i8 @ucmp_poison() {
54 ; CHECK-NEXT:    ret i8 poison
56   %1 = call i8 @llvm.ucmp(i32 poison, i32 5)
57   ret i8 %1
60 define i8 @scmp_poison() {
61 ; CHECK-LABEL: define i8 @scmp_poison() {
62 ; CHECK-NEXT:    ret i8 poison
64   %1 = call i8 @llvm.scmp(i32 0, i32 poison)
65   ret i8 %1
68 define i8 @scmp_undef() {
69 ; CHECK-LABEL: define i8 @scmp_undef() {
70 ; CHECK-NEXT:    ret i8 0
72   %1 = call i8 @llvm.scmp(i32 undef, i32 -12)
73   ret i8 %1
76 define i8 @ucmp_undef() {
77 ; CHECK-LABEL: define i8 @ucmp_undef() {
78 ; CHECK-NEXT:    ret i8 0
80   %1 = call i8 @llvm.ucmp(i32 2, i32 undef)
81   ret i8 %1
84 define <4 x i8> @ucmp_lt_splat() {
85 ; CHECK-LABEL: define <4 x i8> @ucmp_lt_splat() {
86 ; CHECK-NEXT:    ret <4 x i8> <i8 -1, i8 -1, i8 -1, i8 -1>
88   %1 = call <4 x i8> @llvm.ucmp(<4 x i32> splat(i32 1), <4 x i32> splat(i32 3))
89   ret <4 x i8> %1
92 define <4 x i8> @scmp_nonsplat() {
93 ; CHECK-LABEL: define <4 x i8> @scmp_nonsplat() {
94 ; CHECK-NEXT:    ret <4 x i8> <i8 1, i8 0, i8 1, i8 -1>
96   %1 = call <4 x i8> @llvm.scmp(<4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32> <i32 -1, i32 1, i32 -2, i32 4>)
97   ret <4 x i8> %1
100 define i8 @scmp_with_itself(i32 %x) {
101 ; CHECK-LABEL: define i8 @scmp_with_itself(
102 ; CHECK-SAME: i32 [[X:%.*]]) {
103 ; CHECK-NEXT:    ret i8 0
105   %1 = call i8 @llvm.scmp(i32 %x, i32 %x)
106   ret i8 %1
109 define <4 x i8> @ucmp_vec_with_itself(<4 x i32> %x) {
110 ; CHECK-LABEL: define <4 x i8> @ucmp_vec_with_itself(
111 ; CHECK-SAME: <4 x i32> [[X:%.*]]) {
112 ; CHECK-NEXT:    ret <4 x i8> zeroinitializer
114   %1 = call <4 x i8> @llvm.scmp(<4 x i32> %x, <4 x i32> %x)
115   ret <4 x i8> %1
118 define i8 @scmp_known_gt(i32 %x, i32 %y) {
119 ; CHECK-LABEL: define i8 @scmp_known_gt(
120 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
121 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X]], [[Y]]
122 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP1]])
123 ; CHECK-NEXT:    ret i8 1
125   %1 = icmp sgt i32 %x, %y
126   call void @llvm.assume(i1 %1)
128   %2 = call i8 @llvm.scmp(i32 %x, i32 %y)
129   ret i8 %2
132 define i8 @scmp_known_eq(i32 %x, i32 %y) {
133 ; CHECK-LABEL: define i8 @scmp_known_eq(
134 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
135 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[X]], [[Y]]
136 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP1]])
137 ; CHECK-NEXT:    ret i8 0
139   %1 = icmp eq i32 %x, %y
140   call void @llvm.assume(i1 %1)
142   %2 = call i8 @llvm.scmp(i32 %x, i32 %y)
143   ret i8 %2
146 define i8 @scmp_known_lt(i32 %x, i32 %y) {
147 ; CHECK-LABEL: define i8 @scmp_known_lt(
148 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
149 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X]], [[Y]]
150 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP1]])
151 ; CHECK-NEXT:    ret i8 -1
153   %1 = icmp slt i32 %x, %y
154   call void @llvm.assume(i1 %1)
156   %2 = call i8 @llvm.scmp(i32 %x, i32 %y)
157   ret i8 %2
160 define i8 @ucmp_known_gt(i32 %x, i32 %y) {
161 ; CHECK-LABEL: define i8 @ucmp_known_gt(
162 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
163 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X]], [[Y]]
164 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP1]])
165 ; CHECK-NEXT:    ret i8 1
167   %1 = icmp ugt i32 %x, %y
168   call void @llvm.assume(i1 %1)
170   %2 = call i8 @llvm.ucmp(i32 %x, i32 %y)
171   ret i8 %2
174 define i8 @ucmp_known_eq(i32 %x, i32 %y) {
175 ; CHECK-LABEL: define i8 @ucmp_known_eq(
176 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
177 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[X]], [[Y]]
178 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP1]])
179 ; CHECK-NEXT:    ret i8 0
181   %1 = icmp eq i32 %x, %y
182   call void @llvm.assume(i1 %1)
184   %2 = call i8 @llvm.ucmp(i32 %x, i32 %y)
185   ret i8 %2
188 define i8 @ucmp_known_lt(i32 %x, i32 %y) {
189 ; CHECK-LABEL: define i8 @ucmp_known_lt(
190 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
191 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X]], [[Y]]
192 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP1]])
193 ; CHECK-NEXT:    ret i8 -1
195   %1 = icmp ult i32 %x, %y
196   call void @llvm.assume(i1 %1)
198   %2 = call i8 @llvm.ucmp(i32 %x, i32 %y)
199   ret i8 %2
202 define i8 @ucmp_with_addition(i32 %x) {
203 ; CHECK-LABEL: define i8 @ucmp_with_addition(
204 ; CHECK-SAME: i32 [[X:%.*]]) {
205 ; CHECK-NEXT:    ret i8 -1
207   %1 = add nuw i32 %x, 1
208   %2 = call i8 @llvm.ucmp(i32 %x, i32 %1)
209   ret i8 %2
212 define i8 @ucmp_with_addition2(i32 %x) {
213 ; CHECK-LABEL: define i8 @ucmp_with_addition2(
214 ; CHECK-SAME: i32 [[X:%.*]]) {
215 ; CHECK-NEXT:    ret i8 1
217   %1 = add nuw i32 %x, 1
218   %2 = call i8 @llvm.ucmp(i32 %1, i32 %x)
219   ret i8 %2
222 define <4 x i8> @ucmp_with_addition_vec(<4 x i32> %x) {
223 ; CHECK-LABEL: define <4 x i8> @ucmp_with_addition_vec(
224 ; CHECK-SAME: <4 x i32> [[X:%.*]]) {
225 ; CHECK-NEXT:    ret <4 x i8> <i8 -1, i8 -1, i8 -1, i8 -1>
227   %1 = add nuw <4 x i32> %x, splat(i32 1)
228   %2 = call <4 x i8> @llvm.ucmp(<4 x i32> %x, <4 x i32> %1)
229   ret <4 x i8> %2
232 define i1 @scmp_eq_4(i32 %x, i32 %y) {
233 ; CHECK-LABEL: define i1 @scmp_eq_4(
234 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
235 ; CHECK-NEXT:    ret i1 false
237   %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
238   %2 = icmp eq i8 %1, 4
239   ret i1 %2
242 define i1 @ucmp_ne_negative_2(i32 %x, i32 %y) {
243 ; CHECK-LABEL: define i1 @ucmp_ne_negative_2(
244 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
245 ; CHECK-NEXT:    ret i1 true
247   %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
248   %2 = icmp ne i8 %1, -2
249   ret i1 %2
252 ; Negative case: mismatched signedness of predicates
253 define i8 @scmp_known_ugt(i32 %x, i32 %y) {
254 ; CHECK-LABEL: define i8 @scmp_known_ugt(
255 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
256 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X]], [[Y]]
257 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP1]])
258 ; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
259 ; CHECK-NEXT:    ret i8 [[TMP2]]
261   %1 = icmp ugt i32 %x, %y
262   call void @llvm.assume(i1 %1)
264   %2 = call i8 @llvm.scmp(i32 %x, i32 %y)
265   ret i8 %2
268 define i8 @scmp_known_ult(i32 %x, i32 %y) {
269 ; CHECK-LABEL: define i8 @scmp_known_ult(
270 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
271 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X]], [[Y]]
272 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP1]])
273 ; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
274 ; CHECK-NEXT:    ret i8 [[TMP2]]
276   %1 = icmp ult i32 %x, %y
277   call void @llvm.assume(i1 %1)
279   %2 = call i8 @llvm.scmp(i32 %x, i32 %y)
280   ret i8 %2
283 define i8 @ucmp_known_sgt(i32 %x, i32 %y) {
284 ; CHECK-LABEL: define i8 @ucmp_known_sgt(
285 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
286 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X]], [[Y]]
287 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP1]])
288 ; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
289 ; CHECK-NEXT:    ret i8 [[TMP2]]
291   %1 = icmp sgt i32 %x, %y
292   call void @llvm.assume(i1 %1)
294   %2 = call i8 @llvm.ucmp(i32 %x, i32 %y)
295   ret i8 %2
298 define i8 @ucmp_known_slt(i32 %x, i32 %y) {
299 ; CHECK-LABEL: define i8 @ucmp_known_slt(
300 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
301 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X]], [[Y]]
302 ; CHECK-NEXT:    call void @llvm.assume(i1 [[TMP1]])
303 ; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
304 ; CHECK-NEXT:    ret i8 [[TMP2]]
306   %1 = icmp slt i32 %x, %y
307   call void @llvm.assume(i1 %1)
309   %2 = call i8 @llvm.ucmp(i32 %x, i32 %y)
310   ret i8 %2
313 ; Negative case: no nuw flag
314 define i8 @ucmp_with_addition_no_nuw(i32 %x) {
315 ; CHECK-LABEL: define i8 @ucmp_with_addition_no_nuw(
316 ; CHECK-SAME: i32 [[X:%.*]]) {
317 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X]], 1
318 ; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[TMP1]])
319 ; CHECK-NEXT:    ret i8 [[TMP2]]
321   %1 = add i32 %x, 1
322   %2 = call i8 @llvm.ucmp(i32 %x, i32 %1)
323   ret i8 %2