1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
3 ; RUN: | FileCheck %s -check-prefix=RV64I
4 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
5 ; RUN: | FileCheck %s -check-prefix=RV32I
7 ; These tests are each targeted at a particular RISC-V ALU instruction. Other
8 ; files in this folder exercise LLVM IR instructions that don't directly match a
9 ; RISC-V instruction. This file contains tests for the instructions common
10 ; between RV32I and RV64I as well as the *W instructions introduced in RV64I.
12 ; Register-immediate instructions
14 define i64 @addi(i64 %a) nounwind {
17 ; RV64I-NEXT: addi a0, a0, 1
22 ; RV32I-NEXT: addi a2, a0, 1
23 ; RV32I-NEXT: sltu a0, a2, a0
24 ; RV32I-NEXT: add a1, a1, a0
25 ; RV32I-NEXT: mv a0, a2
31 define i64 @slti(i64 %a) nounwind {
34 ; RV64I-NEXT: slti a0, a0, 2
39 ; RV32I-NEXT: beqz a1, .LBB1_2
40 ; RV32I-NEXT: # %bb.1:
41 ; RV32I-NEXT: slti a0, a1, 0
42 ; RV32I-NEXT: mv a1, zero
44 ; RV32I-NEXT: .LBB1_2:
45 ; RV32I-NEXT: sltiu a0, a0, 2
46 ; RV32I-NEXT: mv a1, zero
48 %1 = icmp slt i64 %a, 2
49 %2 = zext i1 %1 to i64
53 define i64 @sltiu(i64 %a) nounwind {
56 ; RV64I-NEXT: sltiu a0, a0, 3
61 ; RV32I-NEXT: beqz a1, .LBB2_2
62 ; RV32I-NEXT: # %bb.1:
63 ; RV32I-NEXT: mv a0, zero
64 ; RV32I-NEXT: mv a1, zero
66 ; RV32I-NEXT: .LBB2_2:
67 ; RV32I-NEXT: sltiu a0, a0, 3
68 ; RV32I-NEXT: mv a1, zero
70 %1 = icmp ult i64 %a, 3
71 %2 = zext i1 %1 to i64
75 define i64 @xori(i64 %a) nounwind {
78 ; RV64I-NEXT: xori a0, a0, 4
83 ; RV32I-NEXT: xori a0, a0, 4
89 define i64 @ori(i64 %a) nounwind {
92 ; RV64I-NEXT: ori a0, a0, 5
97 ; RV32I-NEXT: ori a0, a0, 5
103 define i64 @andi(i64 %a) nounwind {
106 ; RV64I-NEXT: andi a0, a0, 6
111 ; RV32I-NEXT: andi a0, a0, 6
112 ; RV32I-NEXT: mv a1, zero
118 define i64 @slli(i64 %a) nounwind {
121 ; RV64I-NEXT: slli a0, a0, 7
126 ; RV32I-NEXT: slli a1, a1, 7
127 ; RV32I-NEXT: srli a2, a0, 25
128 ; RV32I-NEXT: or a1, a1, a2
129 ; RV32I-NEXT: slli a0, a0, 7
135 define i64 @srli(i64 %a) nounwind {
138 ; RV64I-NEXT: srli a0, a0, 8
143 ; RV32I-NEXT: srli a0, a0, 8
144 ; RV32I-NEXT: slli a2, a1, 24
145 ; RV32I-NEXT: or a0, a0, a2
146 ; RV32I-NEXT: srli a1, a1, 8
152 define i64 @srai(i64 %a) nounwind {
155 ; RV64I-NEXT: srai a0, a0, 9
160 ; RV32I-NEXT: srli a0, a0, 9
161 ; RV32I-NEXT: slli a2, a1, 23
162 ; RV32I-NEXT: or a0, a0, a2
163 ; RV32I-NEXT: srai a1, a1, 9
169 ; Register-register instructions
171 define i64 @add(i64 %a, i64 %b) nounwind {
174 ; RV64I-NEXT: add a0, a0, a1
179 ; RV32I-NEXT: add a1, a1, a3
180 ; RV32I-NEXT: add a2, a0, a2
181 ; RV32I-NEXT: sltu a0, a2, a0
182 ; RV32I-NEXT: add a1, a1, a0
183 ; RV32I-NEXT: mv a0, a2
189 define i64 @sub(i64 %a, i64 %b) nounwind {
192 ; RV64I-NEXT: sub a0, a0, a1
197 ; RV32I-NEXT: sub a1, a1, a3
198 ; RV32I-NEXT: sltu a3, a0, a2
199 ; RV32I-NEXT: sub a1, a1, a3
200 ; RV32I-NEXT: sub a0, a0, a2
206 define i64 @sll(i64 %a, i64 %b) nounwind {
209 ; RV64I-NEXT: sll a0, a0, a1
214 ; RV32I-NEXT: addi a3, a2, -32
215 ; RV32I-NEXT: bltz a3, .LBB11_2
216 ; RV32I-NEXT: # %bb.1:
217 ; RV32I-NEXT: sll a1, a0, a3
218 ; RV32I-NEXT: mv a0, zero
220 ; RV32I-NEXT: .LBB11_2:
221 ; RV32I-NEXT: addi a3, zero, 31
222 ; RV32I-NEXT: sub a3, a3, a2
223 ; RV32I-NEXT: srli a4, a0, 1
224 ; RV32I-NEXT: srl a3, a4, a3
225 ; RV32I-NEXT: sll a1, a1, a2
226 ; RV32I-NEXT: or a1, a1, a3
227 ; RV32I-NEXT: sll a0, a0, a2
233 define i64 @slt(i64 %a, i64 %b) nounwind {
236 ; RV64I-NEXT: slt a0, a0, a1
241 ; RV32I-NEXT: beq a1, a3, .LBB12_2
242 ; RV32I-NEXT: # %bb.1:
243 ; RV32I-NEXT: slt a0, a1, a3
244 ; RV32I-NEXT: mv a1, zero
246 ; RV32I-NEXT: .LBB12_2:
247 ; RV32I-NEXT: sltu a0, a0, a2
248 ; RV32I-NEXT: mv a1, zero
250 %1 = icmp slt i64 %a, %b
251 %2 = zext i1 %1 to i64
255 define i64 @sltu(i64 %a, i64 %b) nounwind {
258 ; RV64I-NEXT: sltu a0, a0, a1
263 ; RV32I-NEXT: beq a1, a3, .LBB13_2
264 ; RV32I-NEXT: # %bb.1:
265 ; RV32I-NEXT: sltu a0, a1, a3
266 ; RV32I-NEXT: mv a1, zero
268 ; RV32I-NEXT: .LBB13_2:
269 ; RV32I-NEXT: sltu a0, a0, a2
270 ; RV32I-NEXT: mv a1, zero
272 %1 = icmp ult i64 %a, %b
273 %2 = zext i1 %1 to i64
277 define i64 @xor(i64 %a, i64 %b) nounwind {
280 ; RV64I-NEXT: xor a0, a0, a1
285 ; RV32I-NEXT: xor a0, a0, a2
286 ; RV32I-NEXT: xor a1, a1, a3
292 define i64 @srl(i64 %a, i64 %b) nounwind {
295 ; RV64I-NEXT: srl a0, a0, a1
300 ; RV32I-NEXT: addi a3, a2, -32
301 ; RV32I-NEXT: bltz a3, .LBB15_2
302 ; RV32I-NEXT: # %bb.1:
303 ; RV32I-NEXT: srl a0, a1, a3
304 ; RV32I-NEXT: mv a1, zero
306 ; RV32I-NEXT: .LBB15_2:
307 ; RV32I-NEXT: addi a3, zero, 31
308 ; RV32I-NEXT: sub a3, a3, a2
309 ; RV32I-NEXT: slli a4, a1, 1
310 ; RV32I-NEXT: sll a3, a4, a3
311 ; RV32I-NEXT: srl a0, a0, a2
312 ; RV32I-NEXT: or a0, a0, a3
313 ; RV32I-NEXT: srl a1, a1, a2
319 define i64 @sra(i64 %a, i64 %b) nounwind {
322 ; RV64I-NEXT: sra a0, a0, a1
327 ; RV32I-NEXT: addi a3, a2, -32
328 ; RV32I-NEXT: bltz a3, .LBB16_2
329 ; RV32I-NEXT: # %bb.1:
330 ; RV32I-NEXT: sra a0, a1, a3
331 ; RV32I-NEXT: srai a1, a1, 31
333 ; RV32I-NEXT: .LBB16_2:
334 ; RV32I-NEXT: addi a3, zero, 31
335 ; RV32I-NEXT: sub a3, a3, a2
336 ; RV32I-NEXT: slli a4, a1, 1
337 ; RV32I-NEXT: sll a3, a4, a3
338 ; RV32I-NEXT: srl a0, a0, a2
339 ; RV32I-NEXT: or a0, a0, a3
340 ; RV32I-NEXT: sra a1, a1, a2
346 define i64 @or(i64 %a, i64 %b) nounwind {
349 ; RV64I-NEXT: or a0, a0, a1
354 ; RV32I-NEXT: or a0, a0, a2
355 ; RV32I-NEXT: or a1, a1, a3
361 define i64 @and(i64 %a, i64 %b) nounwind {
364 ; RV64I-NEXT: and a0, a0, a1
369 ; RV32I-NEXT: and a0, a0, a2
370 ; RV32I-NEXT: and a1, a1, a3
376 ; RV64I-only instructions
378 define signext i32 @addiw(i32 signext %a) nounwind {
379 ; RV64I-LABEL: addiw:
381 ; RV64I-NEXT: addiw a0, a0, 123
384 ; RV32I-LABEL: addiw:
386 ; RV32I-NEXT: addi a0, a0, 123
392 define signext i32 @slliw(i32 signext %a) nounwind {
393 ; RV64I-LABEL: slliw:
395 ; RV64I-NEXT: slliw a0, a0, 17
398 ; RV32I-LABEL: slliw:
400 ; RV32I-NEXT: slli a0, a0, 17
406 define signext i32 @srliw(i32 %a) nounwind {
407 ; RV64I-LABEL: srliw:
409 ; RV64I-NEXT: srliw a0, a0, 8
412 ; RV32I-LABEL: srliw:
414 ; RV32I-NEXT: srli a0, a0, 8
420 define signext i32 @sraiw(i32 %a) nounwind {
421 ; RV64I-LABEL: sraiw:
423 ; RV64I-NEXT: sraiw a0, a0, 9
426 ; RV32I-LABEL: sraiw:
428 ; RV32I-NEXT: srai a0, a0, 9
434 define signext i32 @sextw(i32 zeroext %a) nounwind {
435 ; RV64I-LABEL: sextw:
437 ; RV64I-NEXT: sext.w a0, a0
440 ; RV32I-LABEL: sextw:
446 define signext i32 @addw(i32 signext %a, i32 signext %b) nounwind {
449 ; RV64I-NEXT: addw a0, a0, a1
454 ; RV32I-NEXT: add a0, a0, a1
460 define signext i32 @subw(i32 signext %a, i32 signext %b) nounwind {
463 ; RV64I-NEXT: subw a0, a0, a1
468 ; RV32I-NEXT: sub a0, a0, a1
474 define signext i32 @sllw(i32 signext %a, i32 zeroext %b) nounwind {
477 ; RV64I-NEXT: sllw a0, a0, a1
482 ; RV32I-NEXT: sll a0, a0, a1
488 define signext i32 @srlw(i32 signext %a, i32 zeroext %b) nounwind {
491 ; RV64I-NEXT: srlw a0, a0, a1
496 ; RV32I-NEXT: srl a0, a0, a1
502 define signext i32 @sraw(i64 %a, i32 zeroext %b) nounwind {
505 ; RV64I-NEXT: sraw a0, a0, a1
510 ; RV32I-NEXT: sra a0, a0, a2
512 %1 = trunc i64 %a to i32