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 a0, a0, 1
23 ; RV32I-NEXT: seqz a2, a0
24 ; RV32I-NEXT: add a1, a1, a2
30 define i64 @slti(i64 %a) nounwind {
33 ; RV64I-NEXT: slti a0, a0, 2
38 ; RV32I-NEXT: beqz a1, .LBB1_2
39 ; RV32I-NEXT: # %bb.1:
40 ; RV32I-NEXT: slti a0, a1, 0
41 ; RV32I-NEXT: li a1, 0
43 ; RV32I-NEXT: .LBB1_2:
44 ; RV32I-NEXT: sltiu a0, a0, 2
45 ; RV32I-NEXT: li a1, 0
47 %1 = icmp slt i64 %a, 2
48 %2 = zext i1 %1 to i64
52 define i64 @sltiu(i64 %a) nounwind {
55 ; RV64I-NEXT: sltiu a0, a0, 3
60 ; RV32I-NEXT: sltiu a0, a0, 3
61 ; RV32I-NEXT: seqz a1, a1
62 ; RV32I-NEXT: and a0, a1, a0
63 ; RV32I-NEXT: li a1, 0
65 %1 = icmp ult i64 %a, 3
66 %2 = zext i1 %1 to i64
70 define i64 @xori(i64 %a) nounwind {
73 ; RV64I-NEXT: xori a0, a0, 4
78 ; RV32I-NEXT: xori a0, a0, 4
84 define i64 @ori(i64 %a) nounwind {
87 ; RV64I-NEXT: ori a0, a0, 5
92 ; RV32I-NEXT: ori a0, a0, 5
98 define i64 @andi(i64 %a) nounwind {
101 ; RV64I-NEXT: andi a0, a0, 6
106 ; RV32I-NEXT: andi a0, a0, 6
107 ; RV32I-NEXT: li a1, 0
113 define i64 @slli(i64 %a) nounwind {
116 ; RV64I-NEXT: slli a0, a0, 7
121 ; RV32I-NEXT: srli a2, a0, 25
122 ; RV32I-NEXT: slli a1, a1, 7
123 ; RV32I-NEXT: or a1, a1, a2
124 ; RV32I-NEXT: slli a0, a0, 7
130 define i64 @srli(i64 %a) nounwind {
133 ; RV64I-NEXT: srli a0, a0, 8
138 ; RV32I-NEXT: slli a2, a1, 24
139 ; RV32I-NEXT: srli a0, a0, 8
140 ; RV32I-NEXT: or a0, a0, a2
141 ; RV32I-NEXT: srli a1, a1, 8
147 define i64 @srai(i64 %a) nounwind {
150 ; RV64I-NEXT: srai a0, a0, 9
155 ; RV32I-NEXT: slli a2, a1, 23
156 ; RV32I-NEXT: srli a0, a0, 9
157 ; RV32I-NEXT: or a0, a0, a2
158 ; RV32I-NEXT: srai a1, a1, 9
164 ; Register-register instructions
166 define i64 @add(i64 %a, i64 %b) nounwind {
169 ; RV64I-NEXT: add a0, a0, a1
174 ; RV32I-NEXT: add a1, a1, a3
175 ; RV32I-NEXT: add a2, a0, a2
176 ; RV32I-NEXT: sltu a0, a2, a0
177 ; RV32I-NEXT: add a1, a1, a0
178 ; RV32I-NEXT: mv a0, a2
184 define i64 @sub(i64 %a, i64 %b) nounwind {
187 ; RV64I-NEXT: sub a0, a0, a1
192 ; RV32I-NEXT: sltu a4, a0, a2
193 ; RV32I-NEXT: sub a1, a1, a3
194 ; RV32I-NEXT: sub a1, a1, a4
195 ; RV32I-NEXT: sub a0, a0, a2
201 define i64 @sll(i64 %a, i64 %b) nounwind {
204 ; RV64I-NEXT: sll a0, a0, a1
209 ; RV32I-NEXT: addi a4, a2, -32
210 ; RV32I-NEXT: sll a3, a0, a2
211 ; RV32I-NEXT: bltz a4, .LBB11_2
212 ; RV32I-NEXT: # %bb.1:
213 ; RV32I-NEXT: mv a1, a3
214 ; RV32I-NEXT: j .LBB11_3
215 ; RV32I-NEXT: .LBB11_2:
216 ; RV32I-NEXT: sll a1, a1, a2
217 ; RV32I-NEXT: not a2, a2
218 ; RV32I-NEXT: srli a0, a0, 1
219 ; RV32I-NEXT: srl a0, a0, a2
220 ; RV32I-NEXT: or a1, a1, a0
221 ; RV32I-NEXT: .LBB11_3:
222 ; RV32I-NEXT: srai a0, a4, 31
223 ; RV32I-NEXT: and a0, a0, a3
229 define i64 @slt(i64 %a, i64 %b) nounwind {
232 ; RV64I-NEXT: slt a0, a0, a1
237 ; RV32I-NEXT: beq a1, a3, .LBB12_2
238 ; RV32I-NEXT: # %bb.1:
239 ; RV32I-NEXT: slt a0, a1, a3
240 ; RV32I-NEXT: li a1, 0
242 ; RV32I-NEXT: .LBB12_2:
243 ; RV32I-NEXT: sltu a0, a0, a2
244 ; RV32I-NEXT: li a1, 0
246 %1 = icmp slt i64 %a, %b
247 %2 = zext i1 %1 to i64
251 define i64 @sltu(i64 %a, i64 %b) nounwind {
254 ; RV64I-NEXT: sltu a0, a0, a1
259 ; RV32I-NEXT: beq a1, a3, .LBB13_2
260 ; RV32I-NEXT: # %bb.1:
261 ; RV32I-NEXT: sltu a0, a1, a3
262 ; RV32I-NEXT: li a1, 0
264 ; RV32I-NEXT: .LBB13_2:
265 ; RV32I-NEXT: sltu a0, a0, a2
266 ; RV32I-NEXT: li a1, 0
268 %1 = icmp ult i64 %a, %b
269 %2 = zext i1 %1 to i64
273 define i64 @xor(i64 %a, i64 %b) nounwind {
276 ; RV64I-NEXT: xor a0, a0, a1
281 ; RV32I-NEXT: xor a0, a0, a2
282 ; RV32I-NEXT: xor a1, a1, a3
288 define i64 @srl(i64 %a, i64 %b) nounwind {
291 ; RV64I-NEXT: srl a0, a0, a1
296 ; RV32I-NEXT: addi a4, a2, -32
297 ; RV32I-NEXT: srl a3, a1, a2
298 ; RV32I-NEXT: bltz a4, .LBB15_2
299 ; RV32I-NEXT: # %bb.1:
300 ; RV32I-NEXT: mv a0, a3
301 ; RV32I-NEXT: j .LBB15_3
302 ; RV32I-NEXT: .LBB15_2:
303 ; RV32I-NEXT: srl a0, a0, a2
304 ; RV32I-NEXT: not a2, a2
305 ; RV32I-NEXT: slli a1, a1, 1
306 ; RV32I-NEXT: sll a1, a1, a2
307 ; RV32I-NEXT: or a0, a0, a1
308 ; RV32I-NEXT: .LBB15_3:
309 ; RV32I-NEXT: srai a1, a4, 31
310 ; RV32I-NEXT: and a1, a1, a3
316 define i64 @sra(i64 %a, i64 %b) nounwind {
319 ; RV64I-NEXT: sra a0, a0, a1
324 ; RV32I-NEXT: mv a3, a1
325 ; RV32I-NEXT: addi a4, a2, -32
326 ; RV32I-NEXT: sra a1, a1, a2
327 ; RV32I-NEXT: bltz a4, .LBB16_2
328 ; RV32I-NEXT: # %bb.1:
329 ; RV32I-NEXT: srai a3, a3, 31
330 ; RV32I-NEXT: mv a0, a1
331 ; RV32I-NEXT: mv a1, a3
333 ; RV32I-NEXT: .LBB16_2:
334 ; RV32I-NEXT: srl a0, a0, a2
335 ; RV32I-NEXT: not a2, a2
336 ; RV32I-NEXT: slli a3, a3, 1
337 ; RV32I-NEXT: sll a2, a3, a2
338 ; RV32I-NEXT: or a0, a0, a2
344 define i64 @or(i64 %a, i64 %b) nounwind {
347 ; RV64I-NEXT: or a0, a0, a1
352 ; RV32I-NEXT: or a0, a0, a2
353 ; RV32I-NEXT: or a1, a1, a3
359 define i64 @and(i64 %a, i64 %b) nounwind {
362 ; RV64I-NEXT: and a0, a0, a1
367 ; RV32I-NEXT: and a0, a0, a2
368 ; RV32I-NEXT: and a1, a1, a3
374 ; RV64I-only instructions
376 define signext i32 @addiw(i32 signext %a) nounwind {
377 ; RV64I-LABEL: addiw:
379 ; RV64I-NEXT: addiw a0, a0, 123
382 ; RV32I-LABEL: addiw:
384 ; RV32I-NEXT: addi a0, a0, 123
390 define signext i32 @slliw(i32 signext %a) nounwind {
391 ; RV64I-LABEL: slliw:
393 ; RV64I-NEXT: slliw a0, a0, 17
396 ; RV32I-LABEL: slliw:
398 ; RV32I-NEXT: slli a0, a0, 17
404 define signext i32 @srliw(i32 %a) nounwind {
405 ; RV64I-LABEL: srliw:
407 ; RV64I-NEXT: srliw a0, a0, 8
410 ; RV32I-LABEL: srliw:
412 ; RV32I-NEXT: srli a0, a0, 8
418 define signext i32 @sraiw(i32 %a) nounwind {
419 ; RV64I-LABEL: sraiw:
421 ; RV64I-NEXT: sraiw a0, a0, 9
424 ; RV32I-LABEL: sraiw:
426 ; RV32I-NEXT: srai a0, a0, 9
432 define i64 @sraiw_i64(i64 %a) nounwind {
433 ; RV64I-LABEL: sraiw_i64:
435 ; RV64I-NEXT: sraiw a0, a0, 9
438 ; RV32I-LABEL: sraiw_i64:
440 ; RV32I-NEXT: srai a2, a0, 9
441 ; RV32I-NEXT: srai a1, a0, 31
442 ; RV32I-NEXT: mv a0, a2
449 define signext i32 @sextw(i32 zeroext %a) nounwind {
450 ; RV64I-LABEL: sextw:
452 ; RV64I-NEXT: sext.w a0, a0
455 ; RV32I-LABEL: sextw:
461 define signext i32 @addw(i32 signext %a, i32 signext %b) nounwind {
464 ; RV64I-NEXT: addw a0, a0, a1
469 ; RV32I-NEXT: add a0, a0, a1
475 define signext i32 @subw(i32 signext %a, i32 signext %b) nounwind {
478 ; RV64I-NEXT: subw a0, a0, a1
483 ; RV32I-NEXT: sub a0, a0, a1
489 define signext i32 @sllw(i32 signext %a, i32 zeroext %b) nounwind {
492 ; RV64I-NEXT: sllw a0, a0, a1
497 ; RV32I-NEXT: sll a0, a0, a1
503 define signext i32 @srlw(i32 signext %a, i32 zeroext %b) nounwind {
506 ; RV64I-NEXT: srlw a0, a0, a1
511 ; RV32I-NEXT: srl a0, a0, a1
517 define signext i32 @sraw(i64 %a, i32 zeroext %b) nounwind {
520 ; RV64I-NEXT: sraw a0, a0, a1
525 ; RV32I-NEXT: sra a0, a0, a2
527 %1 = trunc i64 %a to i32
532 define i64 @add_hi_and_lo_negone(i64 %0) {
533 ; RV64I-LABEL: add_hi_and_lo_negone:
535 ; RV64I-NEXT: addi a0, a0, -1
538 ; RV32I-LABEL: add_hi_and_lo_negone:
540 ; RV32I-NEXT: seqz a2, a0
541 ; RV32I-NEXT: sub a1, a1, a2
542 ; RV32I-NEXT: addi a0, a0, -1
544 %2 = add nsw i64 %0, -1
548 define i64 @add_hi_zero_lo_negone(i64 %0) {
549 ; RV64I-LABEL: add_hi_zero_lo_negone:
551 ; RV64I-NEXT: li a1, -1
552 ; RV64I-NEXT: srli a1, a1, 32
553 ; RV64I-NEXT: add a0, a0, a1
556 ; RV32I-LABEL: add_hi_zero_lo_negone:
558 ; RV32I-NEXT: snez a2, a0
559 ; RV32I-NEXT: add a1, a1, a2
560 ; RV32I-NEXT: addi a0, a0, -1
562 %2 = add i64 %0, 4294967295
566 define i64 @add_lo_negone(i64 %0) {
567 ; RV64I-LABEL: add_lo_negone:
569 ; RV64I-NEXT: li a1, -1
570 ; RV64I-NEXT: slli a1, a1, 32
571 ; RV64I-NEXT: addi a1, a1, -1
572 ; RV64I-NEXT: add a0, a0, a1
575 ; RV32I-LABEL: add_lo_negone:
577 ; RV32I-NEXT: snez a2, a0
578 ; RV32I-NEXT: add a1, a1, a2
579 ; RV32I-NEXT: addi a1, a1, -2
580 ; RV32I-NEXT: addi a0, a0, -1
582 %2 = add nsw i64 %0, -4294967297
586 define i64 @add_hi_one_lo_negone(i64 %0) {
587 ; RV64I-LABEL: add_hi_one_lo_negone:
589 ; RV64I-NEXT: li a1, -1
590 ; RV64I-NEXT: srli a1, a1, 31
591 ; RV64I-NEXT: add a0, a0, a1
594 ; RV32I-LABEL: add_hi_one_lo_negone:
596 ; RV32I-NEXT: snez a2, a0
597 ; RV32I-NEXT: add a1, a1, a2
598 ; RV32I-NEXT: addi a1, a1, 1
599 ; RV32I-NEXT: addi a0, a0, -1
601 %2 = add nsw i64 %0, 8589934591