1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=riscv32 -mattr=+m | FileCheck %s --check-prefixes=RV32NoZbt,RV32I
3 ; RUN: llc < %s -mtriple=riscv64 -mattr=+m | FileCheck %s --check-prefixes=RV64NoZbt,RV64I
4 ; RUN: llc < %s -mtriple=riscv32 -mattr=+m,+zbb | FileCheck %s --check-prefixes=RV32NoZbt,RV32IZbb
5 ; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zbb | FileCheck %s --check-prefixes=RV64NoZbt,RV64IZbb
6 ; RUN: llc < %s -mtriple=riscv32 -mattr=+m,+zbb,+experimental-zbt | FileCheck %s --check-prefixes=RV32IZbb,RV32IZbbZbt
7 ; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zbb,+experimental-zbt | FileCheck %s --check-prefixes=RV64IZbb,RV64IZbbZbt
9 declare i4 @llvm.ssub.sat.i4(i4, i4)
10 declare i8 @llvm.ssub.sat.i8(i8, i8)
11 declare i16 @llvm.ssub.sat.i16(i16, i16)
12 declare i32 @llvm.ssub.sat.i32(i32, i32)
13 declare i64 @llvm.ssub.sat.i64(i64, i64)
15 define signext i32 @func(i32 signext %x, i32 signext %y) nounwind {
16 ; RV32NoZbt-LABEL: func:
18 ; RV32NoZbt-NEXT: mv a2, a0
19 ; RV32NoZbt-NEXT: sgtz a3, a1
20 ; RV32NoZbt-NEXT: sub a0, a0, a1
21 ; RV32NoZbt-NEXT: slt a1, a0, a2
22 ; RV32NoZbt-NEXT: beq a3, a1, .LBB0_2
23 ; RV32NoZbt-NEXT: # %bb.1:
24 ; RV32NoZbt-NEXT: srai a0, a0, 31
25 ; RV32NoZbt-NEXT: lui a1, 524288
26 ; RV32NoZbt-NEXT: xor a0, a0, a1
27 ; RV32NoZbt-NEXT: .LBB0_2:
32 ; RV64I-NEXT: sub a0, a0, a1
33 ; RV64I-NEXT: lui a1, 524288
34 ; RV64I-NEXT: addiw a2, a1, -1
35 ; RV64I-NEXT: bge a0, a2, .LBB0_3
36 ; RV64I-NEXT: # %bb.1:
37 ; RV64I-NEXT: bge a1, a0, .LBB0_4
38 ; RV64I-NEXT: .LBB0_2:
40 ; RV64I-NEXT: .LBB0_3:
41 ; RV64I-NEXT: mv a0, a2
42 ; RV64I-NEXT: blt a1, a0, .LBB0_2
43 ; RV64I-NEXT: .LBB0_4:
44 ; RV64I-NEXT: lui a0, 524288
47 ; RV64IZbb-LABEL: func:
49 ; RV64IZbb-NEXT: sub a0, a0, a1
50 ; RV64IZbb-NEXT: lui a1, 524288
51 ; RV64IZbb-NEXT: addiw a2, a1, -1
52 ; RV64IZbb-NEXT: min a0, a0, a2
53 ; RV64IZbb-NEXT: max a0, a0, a1
56 ; RV32IZbbZbt-LABEL: func:
57 ; RV32IZbbZbt: # %bb.0:
58 ; RV32IZbbZbt-NEXT: sgtz a2, a1
59 ; RV32IZbbZbt-NEXT: sub a1, a0, a1
60 ; RV32IZbbZbt-NEXT: slt a0, a1, a0
61 ; RV32IZbbZbt-NEXT: xor a0, a2, a0
62 ; RV32IZbbZbt-NEXT: srai a2, a1, 31
63 ; RV32IZbbZbt-NEXT: lui a3, 524288
64 ; RV32IZbbZbt-NEXT: xor a2, a2, a3
65 ; RV32IZbbZbt-NEXT: cmov a0, a0, a2, a1
66 ; RV32IZbbZbt-NEXT: ret
67 %tmp = call i32 @llvm.ssub.sat.i32(i32 %x, i32 %y);
71 define i64 @func2(i64 %x, i64 %y) nounwind {
72 ; RV32NoZbt-LABEL: func2:
74 ; RV32NoZbt-NEXT: mv a4, a1
75 ; RV32NoZbt-NEXT: sltu a1, a0, a2
76 ; RV32NoZbt-NEXT: sub a5, a4, a3
77 ; RV32NoZbt-NEXT: sub a1, a5, a1
78 ; RV32NoZbt-NEXT: xor a5, a4, a1
79 ; RV32NoZbt-NEXT: xor a3, a4, a3
80 ; RV32NoZbt-NEXT: and a3, a3, a5
81 ; RV32NoZbt-NEXT: bltz a3, .LBB1_2
82 ; RV32NoZbt-NEXT: # %bb.1:
83 ; RV32NoZbt-NEXT: sub a0, a0, a2
85 ; RV32NoZbt-NEXT: .LBB1_2:
86 ; RV32NoZbt-NEXT: srai a0, a1, 31
87 ; RV32NoZbt-NEXT: lui a1, 524288
88 ; RV32NoZbt-NEXT: xor a1, a0, a1
91 ; RV64NoZbt-LABEL: func2:
93 ; RV64NoZbt-NEXT: mv a2, a0
94 ; RV64NoZbt-NEXT: sgtz a3, a1
95 ; RV64NoZbt-NEXT: sub a0, a0, a1
96 ; RV64NoZbt-NEXT: slt a1, a0, a2
97 ; RV64NoZbt-NEXT: beq a3, a1, .LBB1_2
98 ; RV64NoZbt-NEXT: # %bb.1:
99 ; RV64NoZbt-NEXT: srai a0, a0, 63
100 ; RV64NoZbt-NEXT: li a1, -1
101 ; RV64NoZbt-NEXT: slli a1, a1, 63
102 ; RV64NoZbt-NEXT: xor a0, a0, a1
103 ; RV64NoZbt-NEXT: .LBB1_2:
104 ; RV64NoZbt-NEXT: ret
106 ; RV32IZbbZbt-LABEL: func2:
107 ; RV32IZbbZbt: # %bb.0:
108 ; RV32IZbbZbt-NEXT: sltu a4, a0, a2
109 ; RV32IZbbZbt-NEXT: sub a5, a1, a3
110 ; RV32IZbbZbt-NEXT: sub a4, a5, a4
111 ; RV32IZbbZbt-NEXT: srai a5, a4, 31
112 ; RV32IZbbZbt-NEXT: lui a6, 524288
113 ; RV32IZbbZbt-NEXT: xor a6, a5, a6
114 ; RV32IZbbZbt-NEXT: xor a7, a1, a4
115 ; RV32IZbbZbt-NEXT: xor a1, a1, a3
116 ; RV32IZbbZbt-NEXT: and a1, a1, a7
117 ; RV32IZbbZbt-NEXT: slti a3, a1, 0
118 ; RV32IZbbZbt-NEXT: cmov a1, a3, a6, a4
119 ; RV32IZbbZbt-NEXT: sub a0, a0, a2
120 ; RV32IZbbZbt-NEXT: cmov a0, a3, a5, a0
121 ; RV32IZbbZbt-NEXT: ret
123 ; RV64IZbbZbt-LABEL: func2:
124 ; RV64IZbbZbt: # %bb.0:
125 ; RV64IZbbZbt-NEXT: sgtz a2, a1
126 ; RV64IZbbZbt-NEXT: sub a1, a0, a1
127 ; RV64IZbbZbt-NEXT: slt a0, a1, a0
128 ; RV64IZbbZbt-NEXT: xor a0, a2, a0
129 ; RV64IZbbZbt-NEXT: srai a2, a1, 63
130 ; RV64IZbbZbt-NEXT: li a3, -1
131 ; RV64IZbbZbt-NEXT: slli a3, a3, 63
132 ; RV64IZbbZbt-NEXT: xor a2, a2, a3
133 ; RV64IZbbZbt-NEXT: cmov a0, a0, a2, a1
134 ; RV64IZbbZbt-NEXT: ret
135 %tmp = call i64 @llvm.ssub.sat.i64(i64 %x, i64 %y);
139 define signext i16 @func16(i16 signext %x, i16 signext %y) nounwind {
140 ; RV32I-LABEL: func16:
142 ; RV32I-NEXT: sub a0, a0, a1
143 ; RV32I-NEXT: lui a1, 8
144 ; RV32I-NEXT: addi a1, a1, -1
145 ; RV32I-NEXT: bge a0, a1, .LBB2_3
146 ; RV32I-NEXT: # %bb.1:
147 ; RV32I-NEXT: lui a1, 1048568
148 ; RV32I-NEXT: bge a1, a0, .LBB2_4
149 ; RV32I-NEXT: .LBB2_2:
151 ; RV32I-NEXT: .LBB2_3:
152 ; RV32I-NEXT: mv a0, a1
153 ; RV32I-NEXT: lui a1, 1048568
154 ; RV32I-NEXT: blt a1, a0, .LBB2_2
155 ; RV32I-NEXT: .LBB2_4:
156 ; RV32I-NEXT: lui a0, 1048568
159 ; RV64I-LABEL: func16:
161 ; RV64I-NEXT: sub a0, a0, a1
162 ; RV64I-NEXT: lui a1, 8
163 ; RV64I-NEXT: addiw a1, a1, -1
164 ; RV64I-NEXT: bge a0, a1, .LBB2_3
165 ; RV64I-NEXT: # %bb.1:
166 ; RV64I-NEXT: lui a1, 1048568
167 ; RV64I-NEXT: bge a1, a0, .LBB2_4
168 ; RV64I-NEXT: .LBB2_2:
170 ; RV64I-NEXT: .LBB2_3:
171 ; RV64I-NEXT: mv a0, a1
172 ; RV64I-NEXT: lui a1, 1048568
173 ; RV64I-NEXT: blt a1, a0, .LBB2_2
174 ; RV64I-NEXT: .LBB2_4:
175 ; RV64I-NEXT: lui a0, 1048568
178 ; RV32IZbb-LABEL: func16:
180 ; RV32IZbb-NEXT: sub a0, a0, a1
181 ; RV32IZbb-NEXT: lui a1, 8
182 ; RV32IZbb-NEXT: addi a1, a1, -1
183 ; RV32IZbb-NEXT: min a0, a0, a1
184 ; RV32IZbb-NEXT: lui a1, 1048568
185 ; RV32IZbb-NEXT: max a0, a0, a1
188 ; RV64IZbb-LABEL: func16:
190 ; RV64IZbb-NEXT: sub a0, a0, a1
191 ; RV64IZbb-NEXT: lui a1, 8
192 ; RV64IZbb-NEXT: addiw a1, a1, -1
193 ; RV64IZbb-NEXT: min a0, a0, a1
194 ; RV64IZbb-NEXT: lui a1, 1048568
195 ; RV64IZbb-NEXT: max a0, a0, a1
197 %tmp = call i16 @llvm.ssub.sat.i16(i16 %x, i16 %y);
201 define signext i8 @func8(i8 signext %x, i8 signext %y) nounwind {
202 ; RV32I-LABEL: func8:
204 ; RV32I-NEXT: sub a0, a0, a1
205 ; RV32I-NEXT: li a1, 127
206 ; RV32I-NEXT: bge a0, a1, .LBB3_3
207 ; RV32I-NEXT: # %bb.1:
208 ; RV32I-NEXT: li a1, -128
209 ; RV32I-NEXT: bge a1, a0, .LBB3_4
210 ; RV32I-NEXT: .LBB3_2:
212 ; RV32I-NEXT: .LBB3_3:
213 ; RV32I-NEXT: li a0, 127
214 ; RV32I-NEXT: li a1, -128
215 ; RV32I-NEXT: blt a1, a0, .LBB3_2
216 ; RV32I-NEXT: .LBB3_4:
217 ; RV32I-NEXT: li a0, -128
220 ; RV64I-LABEL: func8:
222 ; RV64I-NEXT: sub a0, a0, a1
223 ; RV64I-NEXT: li a1, 127
224 ; RV64I-NEXT: bge a0, a1, .LBB3_3
225 ; RV64I-NEXT: # %bb.1:
226 ; RV64I-NEXT: li a1, -128
227 ; RV64I-NEXT: bge a1, a0, .LBB3_4
228 ; RV64I-NEXT: .LBB3_2:
230 ; RV64I-NEXT: .LBB3_3:
231 ; RV64I-NEXT: li a0, 127
232 ; RV64I-NEXT: li a1, -128
233 ; RV64I-NEXT: blt a1, a0, .LBB3_2
234 ; RV64I-NEXT: .LBB3_4:
235 ; RV64I-NEXT: li a0, -128
238 ; RV32IZbb-LABEL: func8:
240 ; RV32IZbb-NEXT: sub a0, a0, a1
241 ; RV32IZbb-NEXT: li a1, 127
242 ; RV32IZbb-NEXT: min a0, a0, a1
243 ; RV32IZbb-NEXT: li a1, -128
244 ; RV32IZbb-NEXT: max a0, a0, a1
247 ; RV64IZbb-LABEL: func8:
249 ; RV64IZbb-NEXT: sub a0, a0, a1
250 ; RV64IZbb-NEXT: li a1, 127
251 ; RV64IZbb-NEXT: min a0, a0, a1
252 ; RV64IZbb-NEXT: li a1, -128
253 ; RV64IZbb-NEXT: max a0, a0, a1
255 %tmp = call i8 @llvm.ssub.sat.i8(i8 %x, i8 %y);
259 define signext i4 @func3(i4 signext %x, i4 signext %y) nounwind {
260 ; RV32I-LABEL: func3:
262 ; RV32I-NEXT: sub a0, a0, a1
263 ; RV32I-NEXT: li a1, 7
264 ; RV32I-NEXT: bge a0, a1, .LBB4_3
265 ; RV32I-NEXT: # %bb.1:
266 ; RV32I-NEXT: li a1, -8
267 ; RV32I-NEXT: bge a1, a0, .LBB4_4
268 ; RV32I-NEXT: .LBB4_2:
270 ; RV32I-NEXT: .LBB4_3:
271 ; RV32I-NEXT: li a0, 7
272 ; RV32I-NEXT: li a1, -8
273 ; RV32I-NEXT: blt a1, a0, .LBB4_2
274 ; RV32I-NEXT: .LBB4_4:
275 ; RV32I-NEXT: li a0, -8
278 ; RV64I-LABEL: func3:
280 ; RV64I-NEXT: sub a0, a0, a1
281 ; RV64I-NEXT: li a1, 7
282 ; RV64I-NEXT: bge a0, a1, .LBB4_3
283 ; RV64I-NEXT: # %bb.1:
284 ; RV64I-NEXT: li a1, -8
285 ; RV64I-NEXT: bge a1, a0, .LBB4_4
286 ; RV64I-NEXT: .LBB4_2:
288 ; RV64I-NEXT: .LBB4_3:
289 ; RV64I-NEXT: li a0, 7
290 ; RV64I-NEXT: li a1, -8
291 ; RV64I-NEXT: blt a1, a0, .LBB4_2
292 ; RV64I-NEXT: .LBB4_4:
293 ; RV64I-NEXT: li a0, -8
296 ; RV32IZbb-LABEL: func3:
298 ; RV32IZbb-NEXT: sub a0, a0, a1
299 ; RV32IZbb-NEXT: li a1, 7
300 ; RV32IZbb-NEXT: min a0, a0, a1
301 ; RV32IZbb-NEXT: li a1, -8
302 ; RV32IZbb-NEXT: max a0, a0, a1
305 ; RV64IZbb-LABEL: func3:
307 ; RV64IZbb-NEXT: sub a0, a0, a1
308 ; RV64IZbb-NEXT: li a1, 7
309 ; RV64IZbb-NEXT: min a0, a0, a1
310 ; RV64IZbb-NEXT: li a1, -8
311 ; RV64IZbb-NEXT: max a0, a0, a1
313 %tmp = call i4 @llvm.ssub.sat.i4(i4 %x, i4 %y);