1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3 ; RUN: | FileCheck -check-prefix=RV32I %s
4 ; RUN: llc -mtriple=riscv32 -mattr=+m -verify-machineinstrs < %s \
5 ; RUN: | FileCheck -check-prefix=RV32IM %s
6 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
7 ; RUN: | FileCheck -check-prefix=RV64I %s
8 ; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s \
9 ; RUN: | FileCheck -check-prefix=RV64IM %s
11 define signext i32 @square(i32 %a) nounwind {
12 ; RV32I-LABEL: square:
14 ; RV32I-NEXT: addi sp, sp, -16
15 ; RV32I-NEXT: sw ra, 12(sp)
16 ; RV32I-NEXT: mv a1, a0
17 ; RV32I-NEXT: call __mulsi3
18 ; RV32I-NEXT: lw ra, 12(sp)
19 ; RV32I-NEXT: addi sp, sp, 16
22 ; RV32IM-LABEL: square:
24 ; RV32IM-NEXT: mul a0, a0, a0
27 ; RV64I-LABEL: square:
29 ; RV64I-NEXT: addi sp, sp, -16
30 ; RV64I-NEXT: sd ra, 8(sp)
31 ; RV64I-NEXT: mv a1, a0
32 ; RV64I-NEXT: call __muldi3
33 ; RV64I-NEXT: sext.w a0, a0
34 ; RV64I-NEXT: ld ra, 8(sp)
35 ; RV64I-NEXT: addi sp, sp, 16
38 ; RV64IM-LABEL: square:
40 ; RV64IM-NEXT: mulw a0, a0, a0
46 define signext i32 @mul(i32 %a, i32 %b) nounwind {
49 ; RV32I-NEXT: addi sp, sp, -16
50 ; RV32I-NEXT: sw ra, 12(sp)
51 ; RV32I-NEXT: call __mulsi3
52 ; RV32I-NEXT: lw ra, 12(sp)
53 ; RV32I-NEXT: addi sp, sp, 16
58 ; RV32IM-NEXT: mul a0, a0, a1
63 ; RV64I-NEXT: addi sp, sp, -16
64 ; RV64I-NEXT: sd ra, 8(sp)
65 ; RV64I-NEXT: call __muldi3
66 ; RV64I-NEXT: sext.w a0, a0
67 ; RV64I-NEXT: ld ra, 8(sp)
68 ; RV64I-NEXT: addi sp, sp, 16
73 ; RV64IM-NEXT: mulw a0, a0, a1
79 define signext i32 @mul_constant(i32 %a) nounwind {
80 ; RV32I-LABEL: mul_constant:
82 ; RV32I-NEXT: addi sp, sp, -16
83 ; RV32I-NEXT: sw ra, 12(sp)
84 ; RV32I-NEXT: addi a1, zero, 5
85 ; RV32I-NEXT: call __mulsi3
86 ; RV32I-NEXT: lw ra, 12(sp)
87 ; RV32I-NEXT: addi sp, sp, 16
90 ; RV32IM-LABEL: mul_constant:
92 ; RV32IM-NEXT: addi a1, zero, 5
93 ; RV32IM-NEXT: mul a0, a0, a1
96 ; RV64I-LABEL: mul_constant:
98 ; RV64I-NEXT: addi sp, sp, -16
99 ; RV64I-NEXT: sd ra, 8(sp)
100 ; RV64I-NEXT: addi a1, zero, 5
101 ; RV64I-NEXT: call __muldi3
102 ; RV64I-NEXT: sext.w a0, a0
103 ; RV64I-NEXT: ld ra, 8(sp)
104 ; RV64I-NEXT: addi sp, sp, 16
107 ; RV64IM-LABEL: mul_constant:
109 ; RV64IM-NEXT: addi a1, zero, 5
110 ; RV64IM-NEXT: mulw a0, a0, a1
116 define i32 @mul_pow2(i32 %a) nounwind {
117 ; RV32I-LABEL: mul_pow2:
119 ; RV32I-NEXT: slli a0, a0, 3
122 ; RV32IM-LABEL: mul_pow2:
124 ; RV32IM-NEXT: slli a0, a0, 3
127 ; RV64I-LABEL: mul_pow2:
129 ; RV64I-NEXT: slli a0, a0, 3
132 ; RV64IM-LABEL: mul_pow2:
134 ; RV64IM-NEXT: slli a0, a0, 3
140 define i64 @mul64(i64 %a, i64 %b) nounwind {
141 ; RV32I-LABEL: mul64:
143 ; RV32I-NEXT: addi sp, sp, -16
144 ; RV32I-NEXT: sw ra, 12(sp)
145 ; RV32I-NEXT: call __muldi3
146 ; RV32I-NEXT: lw ra, 12(sp)
147 ; RV32I-NEXT: addi sp, sp, 16
150 ; RV32IM-LABEL: mul64:
152 ; RV32IM-NEXT: mul a3, a0, a3
153 ; RV32IM-NEXT: mulhu a4, a0, a2
154 ; RV32IM-NEXT: add a3, a4, a3
155 ; RV32IM-NEXT: mul a1, a1, a2
156 ; RV32IM-NEXT: add a1, a3, a1
157 ; RV32IM-NEXT: mul a0, a0, a2
160 ; RV64I-LABEL: mul64:
162 ; RV64I-NEXT: addi sp, sp, -16
163 ; RV64I-NEXT: sd ra, 8(sp)
164 ; RV64I-NEXT: call __muldi3
165 ; RV64I-NEXT: ld ra, 8(sp)
166 ; RV64I-NEXT: addi sp, sp, 16
169 ; RV64IM-LABEL: mul64:
171 ; RV64IM-NEXT: mul a0, a0, a1
177 define i64 @mul64_constant(i64 %a) nounwind {
178 ; RV32I-LABEL: mul64_constant:
180 ; RV32I-NEXT: addi sp, sp, -16
181 ; RV32I-NEXT: sw ra, 12(sp)
182 ; RV32I-NEXT: addi a2, zero, 5
183 ; RV32I-NEXT: mv a3, zero
184 ; RV32I-NEXT: call __muldi3
185 ; RV32I-NEXT: lw ra, 12(sp)
186 ; RV32I-NEXT: addi sp, sp, 16
189 ; RV32IM-LABEL: mul64_constant:
191 ; RV32IM-NEXT: addi a2, zero, 5
192 ; RV32IM-NEXT: mul a1, a1, a2
193 ; RV32IM-NEXT: mulhu a3, a0, a2
194 ; RV32IM-NEXT: add a1, a3, a1
195 ; RV32IM-NEXT: mul a0, a0, a2
198 ; RV64I-LABEL: mul64_constant:
200 ; RV64I-NEXT: addi sp, sp, -16
201 ; RV64I-NEXT: sd ra, 8(sp)
202 ; RV64I-NEXT: addi a1, zero, 5
203 ; RV64I-NEXT: call __muldi3
204 ; RV64I-NEXT: ld ra, 8(sp)
205 ; RV64I-NEXT: addi sp, sp, 16
208 ; RV64IM-LABEL: mul64_constant:
210 ; RV64IM-NEXT: addi a1, zero, 5
211 ; RV64IM-NEXT: mul a0, a0, a1
217 define i32 @mulhs(i32 %a, i32 %b) nounwind {
218 ; RV32I-LABEL: mulhs:
220 ; RV32I-NEXT: addi sp, sp, -16
221 ; RV32I-NEXT: sw ra, 12(sp)
222 ; RV32I-NEXT: mv a2, a1
223 ; RV32I-NEXT: srai a1, a0, 31
224 ; RV32I-NEXT: srai a3, a2, 31
225 ; RV32I-NEXT: call __muldi3
226 ; RV32I-NEXT: mv a0, a1
227 ; RV32I-NEXT: lw ra, 12(sp)
228 ; RV32I-NEXT: addi sp, sp, 16
231 ; RV32IM-LABEL: mulhs:
233 ; RV32IM-NEXT: mulh a0, a0, a1
236 ; RV64I-LABEL: mulhs:
238 ; RV64I-NEXT: addi sp, sp, -16
239 ; RV64I-NEXT: sd ra, 8(sp)
240 ; RV64I-NEXT: sext.w a0, a0
241 ; RV64I-NEXT: sext.w a1, a1
242 ; RV64I-NEXT: call __muldi3
243 ; RV64I-NEXT: srli a0, a0, 32
244 ; RV64I-NEXT: ld ra, 8(sp)
245 ; RV64I-NEXT: addi sp, sp, 16
248 ; RV64IM-LABEL: mulhs:
250 ; RV64IM-NEXT: sext.w a0, a0
251 ; RV64IM-NEXT: sext.w a1, a1
252 ; RV64IM-NEXT: mul a0, a0, a1
253 ; RV64IM-NEXT: srli a0, a0, 32
255 %1 = sext i32 %a to i64
256 %2 = sext i32 %b to i64
259 %5 = trunc i64 %4 to i32
263 define zeroext i32 @mulhu(i32 zeroext %a, i32 zeroext %b) nounwind {
264 ; RV32I-LABEL: mulhu:
266 ; RV32I-NEXT: addi sp, sp, -16
267 ; RV32I-NEXT: sw ra, 12(sp)
268 ; RV32I-NEXT: mv a2, a1
269 ; RV32I-NEXT: mv a1, zero
270 ; RV32I-NEXT: mv a3, zero
271 ; RV32I-NEXT: call __muldi3
272 ; RV32I-NEXT: mv a0, a1
273 ; RV32I-NEXT: lw ra, 12(sp)
274 ; RV32I-NEXT: addi sp, sp, 16
277 ; RV32IM-LABEL: mulhu:
279 ; RV32IM-NEXT: mulhu a0, a0, a1
282 ; RV64I-LABEL: mulhu:
284 ; RV64I-NEXT: addi sp, sp, -16
285 ; RV64I-NEXT: sd ra, 8(sp)
286 ; RV64I-NEXT: call __muldi3
287 ; RV64I-NEXT: srli a0, a0, 32
288 ; RV64I-NEXT: ld ra, 8(sp)
289 ; RV64I-NEXT: addi sp, sp, 16
292 ; RV64IM-LABEL: mulhu:
294 ; RV64IM-NEXT: mul a0, a0, a1
295 ; RV64IM-NEXT: srli a0, a0, 32
297 %1 = zext i32 %a to i64
298 %2 = zext i32 %b to i64
301 %5 = trunc i64 %4 to i32