[llvm] r329872 - [RISCV] Add tests missed in r329871

Alex Bradbury via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 11 22:36:44 PDT 2018


Author: asb
Date: Wed Apr 11 22:36:44 2018
New Revision: 329872

URL: http://llvm.org/viewvc/llvm-project?rev=329872&view=rev
Log:
[RISCV] Add tests missed in r329871

Added:
    llvm/trunk/test/CodeGen/RISCV/double-arith.ll
    llvm/trunk/test/CodeGen/RISCV/double-calling-conv.ll
    llvm/trunk/test/CodeGen/RISCV/double-imm.ll
    llvm/trunk/test/CodeGen/RISCV/double-intrinsics.ll
    llvm/trunk/test/CodeGen/RISCV/double-mem.ll
    llvm/trunk/test/CodeGen/RISCV/double-stack-spill-restore.ll

Added: llvm/trunk/test/CodeGen/RISCV/double-arith.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/double-arith.ll?rev=329872&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/double-arith.ll (added)
+++ llvm/trunk/test/CodeGen/RISCV/double-arith.ll Wed Apr 11 22:36:44 2018
@@ -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
+}

Added: llvm/trunk/test/CodeGen/RISCV/double-calling-conv.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/double-calling-conv.ll?rev=329872&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/double-calling-conv.ll (added)
+++ llvm/trunk/test/CodeGen/RISCV/double-calling-conv.ll Wed Apr 11 22:36:44 2018
@@ -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
+}

Added: llvm/trunk/test/CodeGen/RISCV/double-imm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/double-imm.ll?rev=329872&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/double-imm.ll (added)
+++ llvm/trunk/test/CodeGen/RISCV/double-imm.ll Wed Apr 11 22:36:44 2018
@@ -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
+}

Added: llvm/trunk/test/CodeGen/RISCV/double-intrinsics.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/double-intrinsics.ll?rev=329872&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/double-intrinsics.ll (added)
+++ llvm/trunk/test/CodeGen/RISCV/double-intrinsics.ll Wed Apr 11 22:36:44 2018
@@ -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
+}

Added: llvm/trunk/test/CodeGen/RISCV/double-mem.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/double-mem.ll?rev=329872&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/double-mem.ll (added)
+++ llvm/trunk/test/CodeGen/RISCV/double-mem.ll Wed Apr 11 22:36:44 2018
@@ -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
+ at 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
+}

Added: llvm/trunk/test/CodeGen/RISCV/double-stack-spill-restore.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/double-stack-spill-restore.ll?rev=329872&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/double-stack-spill-restore.ll (added)
+++ llvm/trunk/test/CodeGen/RISCV/double-stack-spill-restore.ll Wed Apr 11 22:36:44 2018
@@ -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
+}




More information about the llvm-commits mailing list