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 sp, sp, -16
215 ; RV32I-NEXT: sw ra, 12(sp)
216 ; RV32I-NEXT: call __ashldi3
217 ; RV32I-NEXT: lw ra, 12(sp)
218 ; RV32I-NEXT: addi sp, sp, 16
224 define i64 @slt(i64 %a, i64 %b) nounwind {
227 ; RV64I-NEXT: slt a0, a0, a1
232 ; RV32I-NEXT: beq a1, a3, .LBB12_2
233 ; RV32I-NEXT: # %bb.1:
234 ; RV32I-NEXT: slt a0, a1, a3
235 ; RV32I-NEXT: mv a1, zero
237 ; RV32I-NEXT: .LBB12_2:
238 ; RV32I-NEXT: sltu a0, a0, a2
239 ; RV32I-NEXT: mv a1, zero
241 %1 = icmp slt i64 %a, %b
242 %2 = zext i1 %1 to i64
246 define i64 @sltu(i64 %a, i64 %b) nounwind {
249 ; RV64I-NEXT: sltu a0, a0, a1
254 ; RV32I-NEXT: beq a1, a3, .LBB13_2
255 ; RV32I-NEXT: # %bb.1:
256 ; RV32I-NEXT: sltu a0, a1, a3
257 ; RV32I-NEXT: mv a1, zero
259 ; RV32I-NEXT: .LBB13_2:
260 ; RV32I-NEXT: sltu a0, a0, a2
261 ; RV32I-NEXT: mv a1, zero
263 %1 = icmp ult i64 %a, %b
264 %2 = zext i1 %1 to i64
268 define i64 @xor(i64 %a, i64 %b) nounwind {
271 ; RV64I-NEXT: xor a0, a0, a1
276 ; RV32I-NEXT: xor a0, a0, a2
277 ; RV32I-NEXT: xor a1, a1, a3
283 define i64 @srl(i64 %a, i64 %b) nounwind {
286 ; RV64I-NEXT: srl a0, a0, a1
291 ; RV32I-NEXT: addi sp, sp, -16
292 ; RV32I-NEXT: sw ra, 12(sp)
293 ; RV32I-NEXT: call __lshrdi3
294 ; RV32I-NEXT: lw ra, 12(sp)
295 ; RV32I-NEXT: addi sp, sp, 16
301 define i64 @sra(i64 %a, i64 %b) nounwind {
304 ; RV64I-NEXT: sra a0, a0, a1
309 ; RV32I-NEXT: addi sp, sp, -16
310 ; RV32I-NEXT: sw ra, 12(sp)
311 ; RV32I-NEXT: call __ashrdi3
312 ; RV32I-NEXT: lw ra, 12(sp)
313 ; RV32I-NEXT: addi sp, sp, 16
319 define i64 @or(i64 %a, i64 %b) nounwind {
322 ; RV64I-NEXT: or a0, a0, a1
327 ; RV32I-NEXT: or a0, a0, a2
328 ; RV32I-NEXT: or a1, a1, a3
334 define i64 @and(i64 %a, i64 %b) nounwind {
337 ; RV64I-NEXT: and a0, a0, a1
342 ; RV32I-NEXT: and a0, a0, a2
343 ; RV32I-NEXT: and a1, a1, a3
349 ; RV64I-only instructions
351 define signext i32 @addiw(i32 signext %a) {
352 ; RV64I-LABEL: addiw:
354 ; RV64I-NEXT: addiw a0, a0, 123
357 ; RV32I-LABEL: addiw:
359 ; RV32I-NEXT: addi a0, a0, 123
365 define signext i32 @slliw(i32 signext %a) {
366 ; RV64I-LABEL: slliw:
368 ; RV64I-NEXT: slliw a0, a0, 17
371 ; RV32I-LABEL: slliw:
373 ; RV32I-NEXT: slli a0, a0, 17
379 define signext i32 @srliw(i32 %a) {
380 ; RV64I-LABEL: srliw:
382 ; RV64I-NEXT: srliw a0, a0, 8
385 ; RV32I-LABEL: srliw:
387 ; RV32I-NEXT: srli a0, a0, 8
393 define signext i32 @sraiw(i32 %a) {
394 ; RV64I-LABEL: sraiw:
396 ; RV64I-NEXT: sraiw a0, a0, 9
399 ; RV32I-LABEL: sraiw:
401 ; RV32I-NEXT: srai a0, a0, 9
407 define signext i32 @sextw(i32 zeroext %a) {
408 ; RV64I-LABEL: sextw:
410 ; RV64I-NEXT: sext.w a0, a0
413 ; RV32I-LABEL: sextw:
419 define signext i32 @addw(i32 signext %a, i32 signext %b) {
422 ; RV64I-NEXT: addw a0, a0, a1
427 ; RV32I-NEXT: add a0, a0, a1
433 define signext i32 @subw(i32 signext %a, i32 signext %b) {
436 ; RV64I-NEXT: subw a0, a0, a1
441 ; RV32I-NEXT: sub a0, a0, a1
447 define signext i32 @sllw(i32 signext %a, i32 zeroext %b) {
450 ; RV64I-NEXT: sllw a0, a0, a1
455 ; RV32I-NEXT: sll a0, a0, a1
461 define signext i32 @srlw(i32 signext %a, i32 zeroext %b) {
464 ; RV64I-NEXT: srlw a0, a0, a1
469 ; RV32I-NEXT: srl a0, a0, a1
475 define signext i32 @sraw(i64 %a, i32 zeroext %b) {
478 ; RV64I-NEXT: sraw a0, a0, a1
483 ; RV32I-NEXT: sra a0, a0, a2
485 %1 = trunc i64 %a to i32