diff options
| author | Alex Bradbury <asb@lowrisc.org> | 2018-04-12 05:36:44 +0000 |
|---|---|---|
| committer | Alex Bradbury <asb@lowrisc.org> | 2018-04-12 05:36:44 +0000 |
| commit | 8f296478ebbc17daeff51f9d1b84880af5bb726f (patch) | |
| tree | d8aa05e004de0a47bbc5b83f3c8c7cca85067fbd /llvm/test | |
| parent | 0b4175f160a274d02fa556edcc1ccab02a2f01b6 (diff) | |
| download | bcm5719-llvm-8f296478ebbc17daeff51f9d1b84880af5bb726f.tar.gz bcm5719-llvm-8f296478ebbc17daeff51f9d1b84880af5bb726f.zip | |
[RISCV] Add tests missed in r329871
llvm-svn: 329872
Diffstat (limited to 'llvm/test')
| -rw-r--r-- | llvm/test/CodeGen/RISCV/double-arith.ll | 23 | ||||
| -rw-r--r-- | llvm/test/CodeGen/RISCV/double-calling-conv.ll | 160 | ||||
| -rw-r--r-- | llvm/test/CodeGen/RISCV/double-imm.ll | 38 | ||||
| -rw-r--r-- | llvm/test/CodeGen/RISCV/double-intrinsics.ll | 24 | ||||
| -rw-r--r-- | llvm/test/CodeGen/RISCV/double-mem.ll | 172 | ||||
| -rw-r--r-- | llvm/test/CodeGen/RISCV/double-stack-spill-restore.ll | 47 |
6 files changed, 464 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/RISCV/double-arith.ll b/llvm/test/CodeGen/RISCV/double-arith.ll new file mode 100644 index 00000000000..d0e4d786a2f --- /dev/null +++ b/llvm/test/CodeGen/RISCV/double-arith.ll @@ -0,0 +1,23 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV32IFD %s + +define double @fadd_d(double %a, double %b) nounwind { +; RV32IFD-LABEL: fadd_d: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -16 +; RV32IFD-NEXT: sw a2, 8(sp) +; RV32IFD-NEXT: sw a3, 12(sp) +; RV32IFD-NEXT: fld ft0, 8(sp) +; RV32IFD-NEXT: sw a0, 8(sp) +; RV32IFD-NEXT: sw a1, 12(sp) +; RV32IFD-NEXT: fld ft1, 8(sp) +; RV32IFD-NEXT: fadd.d ft0, ft1, ft0 +; RV32IFD-NEXT: fsd ft0, 8(sp) +; RV32IFD-NEXT: lw a0, 8(sp) +; RV32IFD-NEXT: lw a1, 12(sp) +; RV32IFD-NEXT: addi sp, sp, 16 +; RV32IFD-NEXT: ret + %1 = fadd double %a, %b + ret double %1 +} diff --git a/llvm/test/CodeGen/RISCV/double-calling-conv.ll b/llvm/test/CodeGen/RISCV/double-calling-conv.ll new file mode 100644 index 00000000000..aa69e6dbe4c --- /dev/null +++ b/llvm/test/CodeGen/RISCV/double-calling-conv.ll @@ -0,0 +1,160 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV32IFD %s + +; Sanity checks for calling convention lowering for RV32D. This can be +; somewhat error-prone for soft-float RV32D due to the fact that f64 is legal +; but i64 is not, and there is no instruction to move values directly between +; the GPRs and 64-bit FPRs. + +define double @callee_double_inreg(double %a, double %b) nounwind { +; RV32IFD-LABEL: callee_double_inreg: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -16 +; RV32IFD-NEXT: sw a2, 8(sp) +; RV32IFD-NEXT: sw a3, 12(sp) +; RV32IFD-NEXT: fld ft0, 8(sp) +; RV32IFD-NEXT: sw a0, 8(sp) +; RV32IFD-NEXT: sw a1, 12(sp) +; RV32IFD-NEXT: fld ft1, 8(sp) +; RV32IFD-NEXT: fadd.d ft0, ft1, ft0 +; RV32IFD-NEXT: fsd ft0, 8(sp) +; RV32IFD-NEXT: lw a0, 8(sp) +; RV32IFD-NEXT: lw a1, 12(sp) +; RV32IFD-NEXT: addi sp, sp, 16 +; RV32IFD-NEXT: ret + %1 = fadd double %a, %b + ret double %1 +} + +; TODO: code quality for loading and then passing f64 constants is poor. + +define double @caller_double_inreg() nounwind { +; RV32IFD-LABEL: caller_double_inreg: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -16 +; RV32IFD-NEXT: sw ra, 12(sp) +; RV32IFD-NEXT: lui a0, %hi(callee_double_inreg) +; RV32IFD-NEXT: addi a4, a0, %lo(callee_double_inreg) +; RV32IFD-NEXT: lui a0, %hi(.LCPI1_0) +; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI1_0) +; RV32IFD-NEXT: fld ft0, 0(a0) +; RV32IFD-NEXT: lui a0, %hi(.LCPI1_1) +; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI1_1) +; RV32IFD-NEXT: fld ft1, 0(a0) +; RV32IFD-NEXT: fsd ft1, 0(sp) +; RV32IFD-NEXT: lw a0, 0(sp) +; RV32IFD-NEXT: lw a1, 4(sp) +; RV32IFD-NEXT: fsd ft0, 0(sp) +; RV32IFD-NEXT: lw a2, 0(sp) +; RV32IFD-NEXT: lw a3, 4(sp) +; RV32IFD-NEXT: jalr a4 +; RV32IFD-NEXT: lw ra, 12(sp) +; RV32IFD-NEXT: addi sp, sp, 16 +; RV32IFD-NEXT: ret + %1 = call double @callee_double_inreg(double 2.720000e+00, double 3.720000e+00) + ret double %1 +} + +define double @callee_double_split_reg_stack(i32 %a, i64 %b, i64 %c, double %d, double %e) nounwind { +; RV32IFD-LABEL: callee_double_split_reg_stack: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -16 +; RV32IFD-NEXT: lw a0, 16(sp) +; RV32IFD-NEXT: sw a7, 8(sp) +; RV32IFD-NEXT: sw a0, 12(sp) +; RV32IFD-NEXT: fld ft0, 8(sp) +; RV32IFD-NEXT: sw a5, 8(sp) +; RV32IFD-NEXT: sw a6, 12(sp) +; RV32IFD-NEXT: fld ft1, 8(sp) +; RV32IFD-NEXT: fadd.d ft0, ft1, ft0 +; RV32IFD-NEXT: fsd ft0, 8(sp) +; RV32IFD-NEXT: lw a0, 8(sp) +; RV32IFD-NEXT: lw a1, 12(sp) +; RV32IFD-NEXT: addi sp, sp, 16 +; RV32IFD-NEXT: ret + %1 = fadd double %d, %e + ret double %1 +} + +define double @caller_double_split_reg_stack() nounwind { +; RV32IFD-LABEL: caller_double_split_reg_stack: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -32 +; RV32IFD-NEXT: sw ra, 28(sp) +; RV32IFD-NEXT: lui a0, %hi(.LCPI3_0) +; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI3_0) +; RV32IFD-NEXT: fld ft0, 0(a0) +; RV32IFD-NEXT: fsd ft0, 16(sp) +; RV32IFD-NEXT: lw a7, 16(sp) +; RV32IFD-NEXT: lw a0, 20(sp) +; RV32IFD-NEXT: sw a0, 0(sp) +; RV32IFD-NEXT: lui a0, %hi(callee_double_split_reg_stack) +; RV32IFD-NEXT: addi t0, a0, %lo(callee_double_split_reg_stack) +; RV32IFD-NEXT: lui a0, %hi(.LCPI3_1) +; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI3_1) +; RV32IFD-NEXT: fld ft0, 0(a0) +; RV32IFD-NEXT: fsd ft0, 16(sp) +; RV32IFD-NEXT: lw a5, 16(sp) +; RV32IFD-NEXT: lw a6, 20(sp) +; RV32IFD-NEXT: addi a0, zero, 1 +; RV32IFD-NEXT: addi a1, zero, 2 +; RV32IFD-NEXT: addi a3, zero, 3 +; RV32IFD-NEXT: mv a2, zero +; RV32IFD-NEXT: mv a4, zero +; RV32IFD-NEXT: jalr t0 +; RV32IFD-NEXT: lw ra, 28(sp) +; RV32IFD-NEXT: addi sp, sp, 32 +; RV32IFD-NEXT: ret + %1 = call double @callee_double_split_reg_stack(i32 1, i64 2, i64 3, double 4.72, double 5.72) + ret double %1 +} + +define double @callee_double_stack(i64 %a, i64 %b, i64 %c, i64 %d, double %e, double %f) nounwind { +; RV32IFD-LABEL: callee_double_stack: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -16 +; RV32IFD-NEXT: fld ft0, 24(sp) +; RV32IFD-NEXT: fld ft1, 16(sp) +; RV32IFD-NEXT: fadd.d ft0, ft1, ft0 +; RV32IFD-NEXT: fsd ft0, 8(sp) +; RV32IFD-NEXT: lw a0, 8(sp) +; RV32IFD-NEXT: lw a1, 12(sp) +; RV32IFD-NEXT: addi sp, sp, 16 +; RV32IFD-NEXT: ret + %1 = fadd double %e, %f + ret double %1 +} + +define double @caller_double_stack() nounwind { +; RV32IFD-LABEL: caller_double_stack: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -32 +; RV32IFD-NEXT: sw ra, 28(sp) +; RV32IFD-NEXT: lui a0, 262510 +; RV32IFD-NEXT: addi a0, a0, 327 +; RV32IFD-NEXT: sw a0, 4(sp) +; RV32IFD-NEXT: lui a0, 262574 +; RV32IFD-NEXT: addi a0, a0, 327 +; RV32IFD-NEXT: sw a0, 12(sp) +; RV32IFD-NEXT: lui a0, 713032 +; RV32IFD-NEXT: addi a0, a0, -1311 +; RV32IFD-NEXT: sw a0, 0(sp) +; RV32IFD-NEXT: sw a0, 8(sp) +; RV32IFD-NEXT: lui a0, %hi(callee_double_stack) +; RV32IFD-NEXT: addi t0, a0, %lo(callee_double_stack) +; RV32IFD-NEXT: addi a0, zero, 1 +; RV32IFD-NEXT: addi a2, zero, 2 +; RV32IFD-NEXT: addi a4, zero, 3 +; RV32IFD-NEXT: addi a6, zero, 4 +; RV32IFD-NEXT: mv a1, zero +; RV32IFD-NEXT: mv a3, zero +; RV32IFD-NEXT: mv a5, zero +; RV32IFD-NEXT: mv a7, zero +; RV32IFD-NEXT: jalr t0 +; RV32IFD-NEXT: lw ra, 28(sp) +; RV32IFD-NEXT: addi sp, sp, 32 +; RV32IFD-NEXT: ret + %1 = call double @callee_double_stack(i64 1, i64 2, i64 3, i64 4, double 5.72, double 6.72) + ret double %1 +} diff --git a/llvm/test/CodeGen/RISCV/double-imm.ll b/llvm/test/CodeGen/RISCV/double-imm.ll new file mode 100644 index 00000000000..a652d862175 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/double-imm.ll @@ -0,0 +1,38 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV32IFD %s + +define double @double_imm() nounwind { +; RV32IFD-LABEL: double_imm: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -16 +; RV32IFD-NEXT: lui a0, %hi(.LCPI0_0) +; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI0_0) +; RV32IFD-NEXT: fld ft0, 0(a0) +; RV32IFD-NEXT: fsd ft0, 8(sp) +; RV32IFD-NEXT: lw a0, 8(sp) +; RV32IFD-NEXT: lw a1, 12(sp) +; RV32IFD-NEXT: addi sp, sp, 16 +; RV32IFD-NEXT: ret + ret double 3.1415926535897931159979634685441851615905761718750 +} + +define double @double_imm_op(double %a) nounwind { +; RV32IFD-LABEL: double_imm_op: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -16 +; RV32IFD-NEXT: sw a0, 8(sp) +; RV32IFD-NEXT: sw a1, 12(sp) +; RV32IFD-NEXT: fld ft0, 8(sp) +; RV32IFD-NEXT: lui a0, %hi(.LCPI1_0) +; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI1_0) +; RV32IFD-NEXT: fld ft1, 0(a0) +; RV32IFD-NEXT: fadd.d ft0, ft0, ft1 +; RV32IFD-NEXT: fsd ft0, 8(sp) +; RV32IFD-NEXT: lw a0, 8(sp) +; RV32IFD-NEXT: lw a1, 12(sp) +; RV32IFD-NEXT: addi sp, sp, 16 +; RV32IFD-NEXT: ret + %1 = fadd double %a, 1.0 + ret double %1 +} diff --git a/llvm/test/CodeGen/RISCV/double-intrinsics.ll b/llvm/test/CodeGen/RISCV/double-intrinsics.ll new file mode 100644 index 00000000000..cc67472f349 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/double-intrinsics.ll @@ -0,0 +1,24 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV32IFD %s + +declare double @llvm.floor.f64(double) + +; The call to ffloor is introduced very late, meaning this test case covers +; aspects of passing f64 on RV32D soft-float that double-calling-conv.ll +; doesn't. + +define double @foo(double %a) nounwind { +; RV32IFD-LABEL: foo: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -16 +; RV32IFD-NEXT: sw ra, 12(sp) +; RV32IFD-NEXT: lui a2, %hi(floor) +; RV32IFD-NEXT: addi a2, a2, %lo(floor) +; RV32IFD-NEXT: jalr a2 +; RV32IFD-NEXT: lw ra, 12(sp) +; RV32IFD-NEXT: addi sp, sp, 16 +; RV32IFD-NEXT: ret + %1 = call double @llvm.floor.f64(double %a) + ret double %1 +} diff --git a/llvm/test/CodeGen/RISCV/double-mem.ll b/llvm/test/CodeGen/RISCV/double-mem.ll new file mode 100644 index 00000000000..a1f79c883c4 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/double-mem.ll @@ -0,0 +1,172 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV32IFD %s + +define double @fld(double *%a) nounwind { +; RV32IFD-LABEL: fld: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -16 +; RV32IFD-NEXT: fld ft0, 24(a0) +; RV32IFD-NEXT: fld ft1, 0(a0) +; RV32IFD-NEXT: fadd.d ft0, ft1, ft0 +; RV32IFD-NEXT: fsd ft0, 8(sp) +; RV32IFD-NEXT: lw a0, 8(sp) +; RV32IFD-NEXT: lw a1, 12(sp) +; RV32IFD-NEXT: addi sp, sp, 16 +; RV32IFD-NEXT: ret + %1 = load double, double* %a + %2 = getelementptr double, double* %a, i32 3 + %3 = load double, double* %2 +; Use both loaded values in an FP op to ensure an fld is used, even for the +; soft float ABI + %4 = fadd double %1, %3 + ret double %4 +} + +define void @fsd(double *%a, double %b, double %c) nounwind { +; RV32IFD-LABEL: fsd: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -16 +; RV32IFD-NEXT: sw a3, 8(sp) +; RV32IFD-NEXT: sw a4, 12(sp) +; RV32IFD-NEXT: fld ft0, 8(sp) +; RV32IFD-NEXT: sw a1, 8(sp) +; RV32IFD-NEXT: sw a2, 12(sp) +; RV32IFD-NEXT: fld ft1, 8(sp) +; RV32IFD-NEXT: fadd.d ft0, ft1, ft0 +; RV32IFD-NEXT: fsd ft0, 64(a0) +; RV32IFD-NEXT: fsd ft0, 0(a0) +; RV32IFD-NEXT: addi sp, sp, 16 +; RV32IFD-NEXT: ret +; Use %b and %c in an FP op to ensure floating point registers are used, even +; for the soft float ABI + %1 = fadd double %b, %c + store double %1, double* %a + %2 = getelementptr double, double* %a, i32 8 + store double %1, double* %2 + ret void +} + +; Check load and store to a global +@G = global double 0.0 + +define double @fld_fsd_global(double %a, double %b) nounwind { +; RV32IFD-LABEL: fld_fsd_global: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -16 +; RV32IFD-NEXT: sw a2, 8(sp) +; RV32IFD-NEXT: sw a3, 12(sp) +; RV32IFD-NEXT: fld ft0, 8(sp) +; RV32IFD-NEXT: sw a0, 8(sp) +; RV32IFD-NEXT: sw a1, 12(sp) +; RV32IFD-NEXT: fld ft1, 8(sp) +; RV32IFD-NEXT: fadd.d ft0, ft1, ft0 +; RV32IFD-NEXT: lui a0, %hi(G) +; RV32IFD-NEXT: fld ft1, %lo(G)(a0) +; RV32IFD-NEXT: fsd ft0, %lo(G)(a0) +; RV32IFD-NEXT: lui a0, %hi(G+72) +; RV32IFD-NEXT: fld ft1, %lo(G+72)(a0) +; RV32IFD-NEXT: fsd ft0, %lo(G+72)(a0) +; RV32IFD-NEXT: fsd ft0, 8(sp) +; RV32IFD-NEXT: lw a0, 8(sp) +; RV32IFD-NEXT: lw a1, 12(sp) +; RV32IFD-NEXT: addi sp, sp, 16 +; RV32IFD-NEXT: ret +; Use %a and %b in an FP op to ensure floating point registers are used, even +; for the soft float ABI + %1 = fadd double %a, %b + %2 = load volatile double, double* @G + store double %1, double* @G + %3 = getelementptr double, double* @G, i32 9 + %4 = load volatile double, double* %3 + store double %1, double* %3 + ret double %1 +} + +; Ensure that 1 is added to the high 20 bits if bit 11 of the low part is 1 +define double @fld_fsd_constant(double %a) nounwind { +; RV32IFD-LABEL: fld_fsd_constant: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -16 +; RV32IFD-NEXT: sw a0, 8(sp) +; RV32IFD-NEXT: sw a1, 12(sp) +; RV32IFD-NEXT: fld ft0, 8(sp) +; RV32IFD-NEXT: lui a0, 912092 +; RV32IFD-NEXT: fld ft1, -273(a0) +; RV32IFD-NEXT: fadd.d ft0, ft0, ft1 +; RV32IFD-NEXT: fsd ft0, -273(a0) +; RV32IFD-NEXT: fsd ft0, 8(sp) +; RV32IFD-NEXT: lw a0, 8(sp) +; RV32IFD-NEXT: lw a1, 12(sp) +; RV32IFD-NEXT: addi sp, sp, 16 +; RV32IFD-NEXT: ret + %1 = inttoptr i32 3735928559 to double* + %2 = load volatile double, double* %1 + %3 = fadd double %a, %2 + store double %3, double* %1 + ret double %3 +} + +declare void @notdead(i8*) + +define double @fld_stack(double %a) nounwind { +; RV32IFD-LABEL: fld_stack: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -32 +; RV32IFD-NEXT: sw ra, 28(sp) +; RV32IFD-NEXT: sw s1, 24(sp) +; RV32IFD-NEXT: sw s2, 20(sp) +; RV32IFD-NEXT: mv s1, a1 +; RV32IFD-NEXT: mv s2, a0 +; RV32IFD-NEXT: lui a0, %hi(notdead) +; RV32IFD-NEXT: addi a1, a0, %lo(notdead) +; RV32IFD-NEXT: addi a0, sp, 8 +; RV32IFD-NEXT: jalr a1 +; RV32IFD-NEXT: sw s2, 0(sp) +; RV32IFD-NEXT: sw s1, 4(sp) +; RV32IFD-NEXT: fld ft0, 0(sp) +; RV32IFD-NEXT: fld ft1, 8(sp) +; RV32IFD-NEXT: fadd.d ft0, ft1, ft0 +; RV32IFD-NEXT: fsd ft0, 0(sp) +; RV32IFD-NEXT: lw a0, 0(sp) +; RV32IFD-NEXT: lw a1, 4(sp) +; RV32IFD-NEXT: lw s2, 20(sp) +; RV32IFD-NEXT: lw s1, 24(sp) +; RV32IFD-NEXT: lw ra, 28(sp) +; RV32IFD-NEXT: addi sp, sp, 32 +; RV32IFD-NEXT: ret + %1 = alloca double, align 8 + %2 = bitcast double* %1 to i8* + call void @notdead(i8* %2) + %3 = load double, double* %1 + %4 = fadd double %3, %a ; force load in to FPR64 + ret double %4 +} + +define void @fsd_stack(double %a, double %b) nounwind { +; RV32IFD-LABEL: fsd_stack: +; RV32IFD: # %bb.0: +; RV32IFD-NEXT: addi sp, sp, -32 +; RV32IFD-NEXT: sw ra, 28(sp) +; RV32IFD-NEXT: sw a2, 8(sp) +; RV32IFD-NEXT: sw a3, 12(sp) +; RV32IFD-NEXT: fld ft0, 8(sp) +; RV32IFD-NEXT: sw a0, 8(sp) +; RV32IFD-NEXT: sw a1, 12(sp) +; RV32IFD-NEXT: fld ft1, 8(sp) +; RV32IFD-NEXT: fadd.d ft0, ft1, ft0 +; RV32IFD-NEXT: fsd ft0, 16(sp) +; RV32IFD-NEXT: lui a0, %hi(notdead) +; RV32IFD-NEXT: addi a1, a0, %lo(notdead) +; RV32IFD-NEXT: addi a0, sp, 16 +; RV32IFD-NEXT: jalr a1 +; RV32IFD-NEXT: lw ra, 28(sp) +; RV32IFD-NEXT: addi sp, sp, 32 +; RV32IFD-NEXT: ret + %1 = fadd double %a, %b ; force store from FPR64 + %2 = alloca double, align 8 + store double %1, double* %2 + %3 = bitcast double* %2 to i8* + call void @notdead(i8* %3) + ret void +} diff --git a/llvm/test/CodeGen/RISCV/double-stack-spill-restore.ll b/llvm/test/CodeGen/RISCV/double-stack-spill-restore.ll new file mode 100644 index 00000000000..923b9a8c156 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/double-stack-spill-restore.ll @@ -0,0 +1,47 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \ +; RUN: | FileCheck -check-prefix=RV32IFD %s + +define double @func(double %d, i32 %n) nounwind { +; RV32IFD-LABEL: func: +; RV32IFD: # %bb.0: # %entry +; RV32IFD-NEXT: addi sp, sp, -32 +; RV32IFD-NEXT: sw ra, 28(sp) +; RV32IFD-NEXT: sw a0, 16(sp) +; RV32IFD-NEXT: sw a1, 20(sp) +; RV32IFD-NEXT: fld ft0, 16(sp) +; RV32IFD-NEXT: beqz a2, .LBB0_2 +; RV32IFD-NEXT: # %bb.1: # %if.else +; RV32IFD-NEXT: addi a2, a2, -1 +; RV32IFD-NEXT: lui a0, %hi(func) +; RV32IFD-NEXT: addi a3, a0, %lo(func) +; RV32IFD-NEXT: fsd ft0, 16(sp) +; RV32IFD-NEXT: lw a0, 16(sp) +; RV32IFD-NEXT: lw a1, 20(sp) +; RV32IFD-NEXT: fsd ft0, 8(sp) +; RV32IFD-NEXT: jalr a3 +; RV32IFD-NEXT: sw a0, 16(sp) +; RV32IFD-NEXT: sw a1, 20(sp) +; RV32IFD-NEXT: fld ft0, 16(sp) +; RV32IFD-NEXT: fld ft1, 8(sp) +; RV32IFD-NEXT: fadd.d ft0, ft0, ft1 +; RV32IFD-NEXT: .LBB0_2: # %return +; RV32IFD-NEXT: fsd ft0, 16(sp) +; RV32IFD-NEXT: lw a0, 16(sp) +; RV32IFD-NEXT: lw a1, 20(sp) +; RV32IFD-NEXT: lw ra, 28(sp) +; RV32IFD-NEXT: addi sp, sp, 32 +; RV32IFD-NEXT: ret +entry: + %cmp = icmp eq i32 %n, 0 + br i1 %cmp, label %return, label %if.else + +if.else: + %sub = add i32 %n, -1 + %call = tail call double @func(double %d, i32 %sub) + %add = fadd double %call, %d + ret double %add + +return: + ret double %d +} |

