xref: /llvm-project/llvm/test/Transforms/InstCombine/scmp.ll (revision d4798498c4a30efb03eebb56415a69fa60107414)
1905e4ec7SPoseydon42; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2905e4ec7SPoseydon42; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3905e4ec7SPoseydon42
48c664a9fSPoseydon42declare void @use(i8 %value)
58c664a9fSPoseydon42
6905e4ec7SPoseydon42define i1 @scmp_eq_0(i32 %x, i32 %y) {
7905e4ec7SPoseydon42; CHECK-LABEL: define i1 @scmp_eq_0(
8905e4ec7SPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
9905e4ec7SPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[X]], [[Y]]
10905e4ec7SPoseydon42; CHECK-NEXT:    ret i1 [[TMP2]]
11905e4ec7SPoseydon42;
12905e4ec7SPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
13905e4ec7SPoseydon42  %2 = icmp eq i8 %1, 0
14905e4ec7SPoseydon42  ret i1 %2
15905e4ec7SPoseydon42}
16905e4ec7SPoseydon42
17905e4ec7SPoseydon42define i1 @scmp_ne_0(i32 %x, i32 %y) {
18905e4ec7SPoseydon42; CHECK-LABEL: define i1 @scmp_ne_0(
19905e4ec7SPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
20905e4ec7SPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[X]], [[Y]]
21905e4ec7SPoseydon42; CHECK-NEXT:    ret i1 [[TMP2]]
22905e4ec7SPoseydon42;
23905e4ec7SPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
24905e4ec7SPoseydon42  %2 = icmp ne i8 %1, 0
25905e4ec7SPoseydon42  ret i1 %2
26905e4ec7SPoseydon42}
27905e4ec7SPoseydon42
28905e4ec7SPoseydon42define i1 @scmp_eq_1(i32 %x, i32 %y) {
29905e4ec7SPoseydon42; CHECK-LABEL: define i1 @scmp_eq_1(
30905e4ec7SPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
31905e4ec7SPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], [[Y]]
32905e4ec7SPoseydon42; CHECK-NEXT:    ret i1 [[TMP2]]
33905e4ec7SPoseydon42;
34905e4ec7SPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
35905e4ec7SPoseydon42  %2 = icmp eq i8 %1, 1
36905e4ec7SPoseydon42  ret i1 %2
37905e4ec7SPoseydon42}
38905e4ec7SPoseydon42
39905e4ec7SPoseydon42define i1 @scmp_ne_1(i32 %x, i32 %y) {
40905e4ec7SPoseydon42; CHECK-LABEL: define i1 @scmp_ne_1(
41905e4ec7SPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
42905e4ec7SPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = icmp sle i32 [[X]], [[Y]]
43905e4ec7SPoseydon42; CHECK-NEXT:    ret i1 [[TMP2]]
44905e4ec7SPoseydon42;
45905e4ec7SPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
46905e4ec7SPoseydon42  %2 = icmp ne i8 %1, 1
47905e4ec7SPoseydon42  ret i1 %2
48905e4ec7SPoseydon42}
49905e4ec7SPoseydon42
50905e4ec7SPoseydon42define i1 @scmp_eq_negative_1(i32 %x, i32 %y) {
51905e4ec7SPoseydon42; CHECK-LABEL: define i1 @scmp_eq_negative_1(
52905e4ec7SPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
53905e4ec7SPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]
54905e4ec7SPoseydon42; CHECK-NEXT:    ret i1 [[TMP2]]
55905e4ec7SPoseydon42;
56905e4ec7SPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
57905e4ec7SPoseydon42  %2 = icmp eq i8 %1, -1
58905e4ec7SPoseydon42  ret i1 %2
59905e4ec7SPoseydon42}
60905e4ec7SPoseydon42
61905e4ec7SPoseydon42define i1 @scmp_ne_negative_1(i32 %x, i32 %y) {
62905e4ec7SPoseydon42; CHECK-LABEL: define i1 @scmp_ne_negative_1(
63905e4ec7SPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
64905e4ec7SPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = icmp sge i32 [[X]], [[Y]]
65905e4ec7SPoseydon42; CHECK-NEXT:    ret i1 [[TMP2]]
66905e4ec7SPoseydon42;
67905e4ec7SPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
68905e4ec7SPoseydon42  %2 = icmp ne i8 %1, -1
69905e4ec7SPoseydon42  ret i1 %2
70905e4ec7SPoseydon42}
71905e4ec7SPoseydon42
72905e4ec7SPoseydon42define i1 @scmp_sgt_0(i32 %x, i32 %y) {
73905e4ec7SPoseydon42; CHECK-LABEL: define i1 @scmp_sgt_0(
74905e4ec7SPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
75905e4ec7SPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], [[Y]]
76905e4ec7SPoseydon42; CHECK-NEXT:    ret i1 [[TMP2]]
77905e4ec7SPoseydon42;
78905e4ec7SPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
79905e4ec7SPoseydon42  %2 = icmp sgt i8 %1, 0
80905e4ec7SPoseydon42  ret i1 %2
81905e4ec7SPoseydon42}
82905e4ec7SPoseydon42
83905e4ec7SPoseydon42define i1 @scmp_sgt_neg_1(i32 %x, i32 %y) {
84905e4ec7SPoseydon42; CHECK-LABEL: define i1 @scmp_sgt_neg_1(
85905e4ec7SPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
86905e4ec7SPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = icmp sge i32 [[X]], [[Y]]
87905e4ec7SPoseydon42; CHECK-NEXT:    ret i1 [[TMP2]]
88905e4ec7SPoseydon42;
89905e4ec7SPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
90905e4ec7SPoseydon42  %2 = icmp sgt i8 %1, -1
91905e4ec7SPoseydon42  ret i1 %2
92905e4ec7SPoseydon42}
93905e4ec7SPoseydon42
94905e4ec7SPoseydon42define i1 @scmp_sge_0(i32 %x, i32 %y) {
95905e4ec7SPoseydon42; CHECK-LABEL: define i1 @scmp_sge_0(
96905e4ec7SPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
97905e4ec7SPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = icmp sge i32 [[X]], [[Y]]
98905e4ec7SPoseydon42; CHECK-NEXT:    ret i1 [[TMP2]]
99905e4ec7SPoseydon42;
100905e4ec7SPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
101905e4ec7SPoseydon42  %2 = icmp sge i8 %1, 0
102905e4ec7SPoseydon42  ret i1 %2
103905e4ec7SPoseydon42}
104905e4ec7SPoseydon42
105905e4ec7SPoseydon42define i1 @scmp_sge_1(i32 %x, i32 %y) {
106905e4ec7SPoseydon42; CHECK-LABEL: define i1 @scmp_sge_1(
107905e4ec7SPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
108905e4ec7SPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[X]], [[Y]]
109905e4ec7SPoseydon42; CHECK-NEXT:    ret i1 [[TMP2]]
110905e4ec7SPoseydon42;
111905e4ec7SPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
112905e4ec7SPoseydon42  %2 = icmp sge i8 %1, 1
113905e4ec7SPoseydon42  ret i1 %2
114905e4ec7SPoseydon42}
115905e4ec7SPoseydon42
116905e4ec7SPoseydon42define i1 @scmp_slt_0(i32 %x, i32 %y) {
117905e4ec7SPoseydon42; CHECK-LABEL: define i1 @scmp_slt_0(
118905e4ec7SPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
119905e4ec7SPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]
120905e4ec7SPoseydon42; CHECK-NEXT:    ret i1 [[TMP2]]
121905e4ec7SPoseydon42;
122905e4ec7SPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
123905e4ec7SPoseydon42  %2 = icmp slt i8 %1, 0
124905e4ec7SPoseydon42  ret i1 %2
125905e4ec7SPoseydon42}
126905e4ec7SPoseydon42
127905e4ec7SPoseydon42define i1 @scmp_slt_1(i32 %x, i32 %y) {
128905e4ec7SPoseydon42; CHECK-LABEL: define i1 @scmp_slt_1(
129905e4ec7SPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
130905e4ec7SPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = icmp sle i32 [[X]], [[Y]]
131905e4ec7SPoseydon42; CHECK-NEXT:    ret i1 [[TMP2]]
132905e4ec7SPoseydon42;
133905e4ec7SPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
134905e4ec7SPoseydon42  %2 = icmp slt i8 %1, 1
135905e4ec7SPoseydon42  ret i1 %2
136905e4ec7SPoseydon42}
137905e4ec7SPoseydon42
138905e4ec7SPoseydon42define i1 @scmp_sle_0(i32 %x, i32 %y) {
139905e4ec7SPoseydon42; CHECK-LABEL: define i1 @scmp_sle_0(
140905e4ec7SPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
141905e4ec7SPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = icmp sle i32 [[X]], [[Y]]
142905e4ec7SPoseydon42; CHECK-NEXT:    ret i1 [[TMP2]]
143905e4ec7SPoseydon42;
144905e4ec7SPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
145905e4ec7SPoseydon42  %2 = icmp sle i8 %1, 0
146905e4ec7SPoseydon42  ret i1 %2
147905e4ec7SPoseydon42}
148905e4ec7SPoseydon42
149905e4ec7SPoseydon42define i1 @scmp_sle_neg_1(i32 %x, i32 %y) {
150905e4ec7SPoseydon42; CHECK-LABEL: define i1 @scmp_sle_neg_1(
151905e4ec7SPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
152905e4ec7SPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]
153905e4ec7SPoseydon42; CHECK-NEXT:    ret i1 [[TMP2]]
154905e4ec7SPoseydon42;
155905e4ec7SPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
156905e4ec7SPoseydon42  %2 = icmp sle i8 %1, -1
157905e4ec7SPoseydon42  ret i1 %2
158905e4ec7SPoseydon42}
1598c664a9fSPoseydon42
1607e23a23dSVolodymyr Vasylkun; scmp(x, y) u< C => x s>= y when C u> 1 and C != -1
1617e23a23dSVolodymyr Vasylkundefine i1 @scmp_ult_positive_const_gt_than_1_lt_than_umax(i32 %x, i32 %y) {
1627e23a23dSVolodymyr Vasylkun; CHECK-LABEL: define i1 @scmp_ult_positive_const_gt_than_1_lt_than_umax(
1637e23a23dSVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
1647e23a23dSVolodymyr Vasylkun; CHECK-NEXT:    [[TMP1:%.*]] = icmp sge i32 [[X]], [[Y]]
1657e23a23dSVolodymyr Vasylkun; CHECK-NEXT:    ret i1 [[TMP1]]
1667e23a23dSVolodymyr Vasylkun;
1677e23a23dSVolodymyr Vasylkun  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
1687e23a23dSVolodymyr Vasylkun  %2 = icmp ult i8 %1, 4
1697e23a23dSVolodymyr Vasylkun  ret i1 %2
1707e23a23dSVolodymyr Vasylkun}
1717e23a23dSVolodymyr Vasylkun
1727e23a23dSVolodymyr Vasylkun; scmp(x, y) s> C => x s< y when C != 0 and C != -1
1737e23a23dSVolodymyr Vasylkundefine i1 @ucmp_ugt_const_not_0_or_neg1(i32 %x, i32 %y) {
1747e23a23dSVolodymyr Vasylkun; CHECK-LABEL: define i1 @ucmp_ugt_const_not_0_or_neg1(
1757e23a23dSVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
1767e23a23dSVolodymyr Vasylkun; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]
1777e23a23dSVolodymyr Vasylkun; CHECK-NEXT:    ret i1 [[TMP2]]
1787e23a23dSVolodymyr Vasylkun;
1797e23a23dSVolodymyr Vasylkun  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
1807e23a23dSVolodymyr Vasylkun  %2 = icmp ugt i8 %1, 12
1817e23a23dSVolodymyr Vasylkun  ret i1 %2
1827e23a23dSVolodymyr Vasylkun}
1837e23a23dSVolodymyr Vasylkun
1847e23a23dSVolodymyr Vasylkun
1858c664a9fSPoseydon42; ========== Fold -scmp(x, y) => scmp(y, x) ==========
1868c664a9fSPoseydon42define i8 @scmp_negated(i32 %x, i32 %y) {
1878c664a9fSPoseydon42; CHECK-LABEL: define i8 @scmp_negated(
1888c664a9fSPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
1898c664a9fSPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
1908c664a9fSPoseydon42; CHECK-NEXT:    ret i8 [[TMP2]]
1918c664a9fSPoseydon42;
1928c664a9fSPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
1938c664a9fSPoseydon42  %2 = sub i8 0, %1
1948c664a9fSPoseydon42  ret i8 %2
1958c664a9fSPoseydon42}
1968c664a9fSPoseydon42
1978c664a9fSPoseydon42; Negative test: do not fold if the original scmp result is already used
1988c664a9fSPoseydon42define i8 @scmp_negated_multiuse(i32 %x, i32 %y) {
1998c664a9fSPoseydon42; CHECK-LABEL: define i8 @scmp_negated_multiuse(
2008c664a9fSPoseydon42; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
2018c664a9fSPoseydon42; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
2028c664a9fSPoseydon42; CHECK-NEXT:    call void @use(i8 [[TMP1]])
2038c664a9fSPoseydon42; CHECK-NEXT:    [[TMP2:%.*]] = sub nsw i8 0, [[TMP1]]
2048c664a9fSPoseydon42; CHECK-NEXT:    ret i8 [[TMP2]]
2058c664a9fSPoseydon42;
2068c664a9fSPoseydon42  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
2078c664a9fSPoseydon42  call void @use(i8 %1)
2088c664a9fSPoseydon42  %2 = sub i8 0, %1
2098c664a9fSPoseydon42  ret i8 %2
2108c664a9fSPoseydon42}
211abf69a16SVolodymyr Vasylkun
212abf69a16SVolodymyr Vasylkun; Fold ((x s< y) ? -1 : (x != y)) into scmp(x, y)
213abf69a16SVolodymyr Vasylkundefine i8 @scmp_from_select_lt(i32 %x, i32 %y) {
214abf69a16SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_from_select_lt(
215abf69a16SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
216abf69a16SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
217abf69a16SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
218abf69a16SVolodymyr Vasylkun;
219abf69a16SVolodymyr Vasylkun  %ne_bool = icmp ne i32 %x, %y
220abf69a16SVolodymyr Vasylkun  %ne = zext i1 %ne_bool to i8
221abf69a16SVolodymyr Vasylkun  %lt = icmp slt i32 %x, %y
222abf69a16SVolodymyr Vasylkun  %r = select i1 %lt, i8 -1, i8 %ne
223abf69a16SVolodymyr Vasylkun  ret i8 %r
224abf69a16SVolodymyr Vasylkun}
225abf69a16SVolodymyr Vasylkun
226da6f4232SVolodymyr Vasylkun; Fold (x s< y) ? -1 : zext(x s> y) into scmp(x, y)
227da6f4232SVolodymyr Vasylkundefine i8 @scmp_from_select_lt_and_gt(i32 %x, i32 %y) {
228da6f4232SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_from_select_lt_and_gt(
229da6f4232SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
230da6f4232SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
231da6f4232SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
232da6f4232SVolodymyr Vasylkun;
233da6f4232SVolodymyr Vasylkun  %gt_bool = icmp sgt i32 %x, %y
234da6f4232SVolodymyr Vasylkun  %gt = zext i1 %gt_bool to i8
235da6f4232SVolodymyr Vasylkun  %lt = icmp slt i32 %x, %y
236da6f4232SVolodymyr Vasylkun  %r = select i1 %lt, i8 -1, i8 %gt
237da6f4232SVolodymyr Vasylkun  ret i8 %r
238da6f4232SVolodymyr Vasylkun}
239da6f4232SVolodymyr Vasylkun
240abf69a16SVolodymyr Vasylkun; Vector version
241abf69a16SVolodymyr Vasylkundefine <4 x i8> @scmp_from_select_vec_lt(<4 x i32> %x, <4 x i32> %y) {
242abf69a16SVolodymyr Vasylkun; CHECK-LABEL: define <4 x i8> @scmp_from_select_vec_lt(
243abf69a16SVolodymyr Vasylkun; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
244abf69a16SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call <4 x i8> @llvm.scmp.v4i8.v4i32(<4 x i32> [[X]], <4 x i32> [[Y]])
245abf69a16SVolodymyr Vasylkun; CHECK-NEXT:    ret <4 x i8> [[R]]
246abf69a16SVolodymyr Vasylkun;
247abf69a16SVolodymyr Vasylkun  %ne_bool = icmp ne <4 x i32> %x, %y
248abf69a16SVolodymyr Vasylkun  %ne = zext <4 x i1> %ne_bool to <4 x i8>
249abf69a16SVolodymyr Vasylkun  %lt = icmp slt <4 x i32> %x, %y
250abf69a16SVolodymyr Vasylkun  %r = select <4 x i1> %lt, <4 x i8> splat(i8 -1), <4 x i8> %ne
251abf69a16SVolodymyr Vasylkun  ret <4 x i8> %r
252abf69a16SVolodymyr Vasylkun}
253abf69a16SVolodymyr Vasylkun
254abf69a16SVolodymyr Vasylkun; Fold (x s<= y) ? sext(x != y) : 1 into scmp(x, y)
255abf69a16SVolodymyr Vasylkundefine i8 @scmp_from_select_le(i32 %x, i32 %y) {
256abf69a16SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_from_select_le(
257abf69a16SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
258abf69a16SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
259abf69a16SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
260abf69a16SVolodymyr Vasylkun;
261abf69a16SVolodymyr Vasylkun  %ne_bool = icmp ne i32 %x, %y
262abf69a16SVolodymyr Vasylkun  %ne = sext i1 %ne_bool to i8
263abf69a16SVolodymyr Vasylkun  %le = icmp sle i32 %x, %y
264abf69a16SVolodymyr Vasylkun  %r = select i1 %le, i8 %ne, i8 1
265abf69a16SVolodymyr Vasylkun  ret i8 %r
266abf69a16SVolodymyr Vasylkun}
267abf69a16SVolodymyr Vasylkun
268abf69a16SVolodymyr Vasylkun; Fold (x s>= y) ? zext(x != y) : -1 into scmp(x, y)
269abf69a16SVolodymyr Vasylkundefine i8 @scmp_from_select_ge(i32 %x, i32 %y) {
270abf69a16SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_from_select_ge(
271abf69a16SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
272abf69a16SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
273abf69a16SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
274abf69a16SVolodymyr Vasylkun;
275abf69a16SVolodymyr Vasylkun  %ne_bool = icmp ne i32 %x, %y
276abf69a16SVolodymyr Vasylkun  %ne = zext i1 %ne_bool to i8
277abf69a16SVolodymyr Vasylkun  %ge = icmp sge i32 %x, %y
278abf69a16SVolodymyr Vasylkun  %r = select i1 %ge, i8 %ne, i8 -1
279abf69a16SVolodymyr Vasylkun  ret i8 %r
280abf69a16SVolodymyr Vasylkun}
281d1639355SVolodymyr Vasylkun
282d1639355SVolodymyr Vasylkun; Fold scmp(x nsw- y, 0) to scmp(x, y)
283d1639355SVolodymyr Vasylkundefine i8 @scmp_of_sub_and_zero(i32 %x, i32 %y) {
284d1639355SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_of_sub_and_zero(
285d1639355SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
286d1639355SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
287d1639355SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
288d1639355SVolodymyr Vasylkun;
289d1639355SVolodymyr Vasylkun  %diff = sub nsw i32 %x, %y
290d1639355SVolodymyr Vasylkun  %r = call i8 @llvm.scmp(i32 %diff, i32 0)
291d1639355SVolodymyr Vasylkun  ret i8 %r
292d1639355SVolodymyr Vasylkun}
293d1639355SVolodymyr Vasylkun
294d1639355SVolodymyr Vasylkun; Negative test: no nsw
295d1639355SVolodymyr Vasylkundefine i8 @scmp_of_sub_and_zero_neg_1(i32 %x, i32 %y) {
296d1639355SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_of_sub_and_zero_neg_1(
297d1639355SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
298d1639355SVolodymyr Vasylkun; CHECK-NEXT:    [[DIFF:%.*]] = sub i32 [[X]], [[Y]]
299d1639355SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[DIFF]], i32 0)
300d1639355SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
301d1639355SVolodymyr Vasylkun;
302d1639355SVolodymyr Vasylkun  %diff = sub i32 %x, %y
303d1639355SVolodymyr Vasylkun  %r = call i8 @llvm.scmp(i32 %diff, i32 0)
304d1639355SVolodymyr Vasylkun  ret i8 %r
305d1639355SVolodymyr Vasylkun}
306d1639355SVolodymyr Vasylkun
307d1639355SVolodymyr Vasylkun; Negative test: second argument of scmp is not 0
308d1639355SVolodymyr Vasylkundefine i8 @scmp_of_sub_and_zero_neg2(i32 %x, i32 %y) {
309d1639355SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_of_sub_and_zero_neg2(
310d1639355SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
311d1639355SVolodymyr Vasylkun; CHECK-NEXT:    [[DIFF:%.*]] = sub nsw i32 [[X]], [[Y]]
312d1639355SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[DIFF]], i32 15)
313d1639355SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
314d1639355SVolodymyr Vasylkun;
315d1639355SVolodymyr Vasylkun  %diff = sub nsw i32 %x, %y
316d1639355SVolodymyr Vasylkun  %r = call i8 @llvm.scmp(i32 %diff, i32 15)
317d1639355SVolodymyr Vasylkun  ret i8 %r
318d1639355SVolodymyr Vasylkun}
319d1639355SVolodymyr Vasylkun
320d1639355SVolodymyr Vasylkun; Negative test: calling ucmp instead of scmp
321d1639355SVolodymyr Vasylkundefine i8 @scmp_of_sub_and_zero_neg3(i32 %x, i32 %y) {
322d1639355SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_of_sub_and_zero_neg3(
323d1639355SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
324d1639355SVolodymyr Vasylkun; CHECK-NEXT:    [[DIFF:%.*]] = sub nsw i32 [[X]], [[Y]]
325d1639355SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[DIFF]], i32 0)
326d1639355SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
327d1639355SVolodymyr Vasylkun;
328d1639355SVolodymyr Vasylkun  %diff = sub nsw i32 %x, %y
329d1639355SVolodymyr Vasylkun  %r = call i8 @llvm.ucmp(i32 %diff, i32 0)
330d1639355SVolodymyr Vasylkun  ret i8 %r
331d1639355SVolodymyr Vasylkun}
332da6f4232SVolodymyr Vasylkun
333da6f4232SVolodymyr Vasylkun; Fold (x s> y) ? 1 : sext(x s< y)
334da6f4232SVolodymyr Vasylkundefine i8 @scmp_from_select_gt_and_lt(i32 %x, i32 %y) {
335da6f4232SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_from_select_gt_and_lt(
336da6f4232SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
337da6f4232SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
338da6f4232SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
339da6f4232SVolodymyr Vasylkun;
340da6f4232SVolodymyr Vasylkun  %lt_bool = icmp slt i32 %x, %y
341da6f4232SVolodymyr Vasylkun  %lt = sext i1 %lt_bool to i8
342da6f4232SVolodymyr Vasylkun  %gt = icmp sgt i32 %x, %y
343da6f4232SVolodymyr Vasylkun  %r = select i1 %gt, i8 1, i8 %lt
344da6f4232SVolodymyr Vasylkun  ret i8 %r
345da6f4232SVolodymyr Vasylkun}
346*d4798498SVolodymyr Vasylkun
347*d4798498SVolodymyr Vasylkun; (x == y) ? 0 : (x s> y ? 1 : -1) into scmp(x, y)
348*d4798498SVolodymyr Vasylkundefine i8 @scmp_from_select_eq_and_gt(i32 %x, i32 %y) {
349*d4798498SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt(
350*d4798498SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
351*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
352*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
353*d4798498SVolodymyr Vasylkun;
354*d4798498SVolodymyr Vasylkun  %eq = icmp eq i32 %x, %y
355*d4798498SVolodymyr Vasylkun  %gt = icmp sgt i32 %x, %y
356*d4798498SVolodymyr Vasylkun  %sel1 = select i1 %gt, i8 1, i8 -1
357*d4798498SVolodymyr Vasylkun  %r = select i1 %eq, i8 0, i8 %sel1
358*d4798498SVolodymyr Vasylkun  ret i8 %r
359*d4798498SVolodymyr Vasylkun}
360*d4798498SVolodymyr Vasylkun
361*d4798498SVolodymyr Vasylkundefine i8 @scmp_from_select_eq_and_gt_inverse(i32 %x, i32 %y) {
362*d4798498SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_inverse(
363*d4798498SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
364*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
365*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
366*d4798498SVolodymyr Vasylkun;
367*d4798498SVolodymyr Vasylkun  %ne = icmp ne i32 %x, %y
368*d4798498SVolodymyr Vasylkun  %gt = icmp sgt i32 %x, %y
369*d4798498SVolodymyr Vasylkun  %sel1 = select i1 %gt, i8 1, i8 -1
370*d4798498SVolodymyr Vasylkun  %r = select i1 %ne, i8 %sel1, i8 0
371*d4798498SVolodymyr Vasylkun  ret i8 %r
372*d4798498SVolodymyr Vasylkun}
373*d4798498SVolodymyr Vasylkun
374*d4798498SVolodymyr Vasylkundefine <4 x i8> @scmp_from_select_eq_and_gt_vec(<4 x i32> %x, <4 x i32> %y) {
375*d4798498SVolodymyr Vasylkun; CHECK-LABEL: define <4 x i8> @scmp_from_select_eq_and_gt_vec(
376*d4798498SVolodymyr Vasylkun; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
377*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call <4 x i8> @llvm.scmp.v4i8.v4i32(<4 x i32> [[X]], <4 x i32> [[Y]])
378*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    ret <4 x i8> [[R]]
379*d4798498SVolodymyr Vasylkun;
380*d4798498SVolodymyr Vasylkun  %eq = icmp eq <4 x i32> %x, %y
381*d4798498SVolodymyr Vasylkun  %gt = icmp sgt <4 x i32> %x, %y
382*d4798498SVolodymyr Vasylkun  %sel1 = select <4 x i1> %gt, <4 x i8> splat(i8 1), <4 x i8> splat(i8 -1)
383*d4798498SVolodymyr Vasylkun  %r = select <4 x i1> %eq, <4 x i8> splat(i8 0), <4 x i8> %sel1
384*d4798498SVolodymyr Vasylkun  ret <4 x i8> %r
385*d4798498SVolodymyr Vasylkun}
386*d4798498SVolodymyr Vasylkun
387*d4798498SVolodymyr Vasylkundefine i8 @scmp_from_select_eq_and_gt_commuted1(i32 %x, i32 %y) {
388*d4798498SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted1(
389*d4798498SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
390*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
391*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
392*d4798498SVolodymyr Vasylkun;
393*d4798498SVolodymyr Vasylkun  %eq = icmp eq i32 %x, %y
394*d4798498SVolodymyr Vasylkun  %gt = icmp slt i32 %x, %y
395*d4798498SVolodymyr Vasylkun  %sel1 = select i1 %gt, i8 1, i8 -1
396*d4798498SVolodymyr Vasylkun  %r = select i1 %eq, i8 0, i8 %sel1
397*d4798498SVolodymyr Vasylkun  ret i8 %r
398*d4798498SVolodymyr Vasylkun}
399*d4798498SVolodymyr Vasylkun
400*d4798498SVolodymyr Vasylkundefine i8 @scmp_from_select_eq_and_gt_commuted2(i32 %x, i32 %y) {
401*d4798498SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted2(
402*d4798498SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
403*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[Y]], i32 [[X]])
404*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
405*d4798498SVolodymyr Vasylkun;
406*d4798498SVolodymyr Vasylkun  %eq = icmp eq i32 %x, %y
407*d4798498SVolodymyr Vasylkun  %gt = icmp sgt i32 %x, %y
408*d4798498SVolodymyr Vasylkun  %sel1 = select i1 %gt, i8 -1, i8 1
409*d4798498SVolodymyr Vasylkun  %r = select i1 %eq, i8 0, i8 %sel1
410*d4798498SVolodymyr Vasylkun  ret i8 %r
411*d4798498SVolodymyr Vasylkun}
412*d4798498SVolodymyr Vasylkun
413*d4798498SVolodymyr Vasylkundefine i8 @scmp_from_select_eq_and_gt_commuted3(i32 %x, i32 %y) {
414*d4798498SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_commuted3(
415*d4798498SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
416*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
417*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
418*d4798498SVolodymyr Vasylkun;
419*d4798498SVolodymyr Vasylkun  %eq = icmp eq i32 %x, %y
420*d4798498SVolodymyr Vasylkun  %gt = icmp slt i32 %x, %y
421*d4798498SVolodymyr Vasylkun  %sel1 = select i1 %gt, i8 -1, i8 1
422*d4798498SVolodymyr Vasylkun  %r = select i1 %eq, i8 0, i8 %sel1
423*d4798498SVolodymyr Vasylkun  ret i8 %r
424*d4798498SVolodymyr Vasylkun}
425*d4798498SVolodymyr Vasylkun
426*d4798498SVolodymyr Vasylkun; Negative test: true value of outer select is not zero
427*d4798498SVolodymyr Vasylkundefine i8 @scmp_from_select_eq_and_gt_neg1(i32 %x, i32 %y) {
428*d4798498SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg1(
429*d4798498SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
430*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
431*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
432*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 -1
433*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = select i1 [[EQ]], i8 5, i8 [[SEL1]]
434*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
435*d4798498SVolodymyr Vasylkun;
436*d4798498SVolodymyr Vasylkun  %eq = icmp eq i32 %x, %y
437*d4798498SVolodymyr Vasylkun  %gt = icmp sgt i32 %x, %y
438*d4798498SVolodymyr Vasylkun  %sel1 = select i1 %gt, i8 1, i8 -1
439*d4798498SVolodymyr Vasylkun  %r = select i1 %eq, i8 5, i8 %sel1
440*d4798498SVolodymyr Vasylkun  ret i8 %r
441*d4798498SVolodymyr Vasylkun}
442*d4798498SVolodymyr Vasylkun
443*d4798498SVolodymyr Vasylkun; Negative test: true value of inner select is not 1 or -1
444*d4798498SVolodymyr Vasylkundefine i8 @scmp_from_select_eq_and_gt_neg2(i32 %x, i32 %y) {
445*d4798498SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg2(
446*d4798498SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
447*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
448*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
449*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[GT]], i8 2, i8 -1
450*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
451*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
452*d4798498SVolodymyr Vasylkun;
453*d4798498SVolodymyr Vasylkun  %eq = icmp eq i32 %x, %y
454*d4798498SVolodymyr Vasylkun  %gt = icmp sgt i32 %x, %y
455*d4798498SVolodymyr Vasylkun  %sel1 = select i1 %gt, i8 2, i8 -1
456*d4798498SVolodymyr Vasylkun  %r = select i1 %eq, i8 0, i8 %sel1
457*d4798498SVolodymyr Vasylkun  ret i8 %r
458*d4798498SVolodymyr Vasylkun}
459*d4798498SVolodymyr Vasylkun
460*d4798498SVolodymyr Vasylkun; Negative test: false value of inner select is not 1 or -1
461*d4798498SVolodymyr Vasylkundefine i8 @scmp_from_select_eq_and_gt_neg3(i32 %x, i32 %y) {
462*d4798498SVolodymyr Vasylkun; CHECK-LABEL: define i8 @scmp_from_select_eq_and_gt_neg3(
463*d4798498SVolodymyr Vasylkun; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
464*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[EQ:%.*]] = icmp eq i32 [[X]], [[Y]]
465*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[GT:%.*]] = icmp sgt i32 [[X]], [[Y]]
466*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[GT]], i8 1, i8 22
467*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    [[R:%.*]] = select i1 [[EQ]], i8 0, i8 [[SEL1]]
468*d4798498SVolodymyr Vasylkun; CHECK-NEXT:    ret i8 [[R]]
469*d4798498SVolodymyr Vasylkun;
470*d4798498SVolodymyr Vasylkun  %eq = icmp eq i32 %x, %y
471*d4798498SVolodymyr Vasylkun  %gt = icmp sgt i32 %x, %y
472*d4798498SVolodymyr Vasylkun  %sel1 = select i1 %gt, i8 1, i8 22
473*d4798498SVolodymyr Vasylkun  %r = select i1 %eq, i8 0, i8 %sel1
474*d4798498SVolodymyr Vasylkun  ret i8 %r
475*d4798498SVolodymyr Vasylkun}
476