[RISCV] Add tests for callee-saved GPRs, FPR32s, and FPR64s

Note that s0 need not be marked reserved if the frame pointer isn't used. For
the ILP32 and LP64 soft float ABIS that are currently support, all FPRs are
always considered temporaries.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356061 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGen/RISCV/callee-saved-fpr32s.ll b/test/CodeGen/RISCV/callee-saved-fpr32s.ll
new file mode 100644
index 0000000..6ec18aa
--- /dev/null
+++ b/test/CodeGen/RISCV/callee-saved-fpr32s.ll
@@ -0,0 +1,84 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s -check-prefix=ILP32-LP64
+; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s -check-prefix=ILP32-LP64
+
+@var = global [32 x float] zeroinitializer
+
+; All floating point registers are temporaries for the ilp32 and lp64 ABIs.
+
+define void @foo() {
+; ILP32-LP64-LABEL: foo:
+; ILP32-LP64:       # %bb.0:
+; ILP32-LP64-NEXT:    lui a0, %hi(var)
+; ILP32-LP64-NEXT:    addi a1, a0, %lo(var)
+; ILP32-LP64-NEXT:    flw ft0, %lo(var)(a0)
+; ILP32-LP64-NEXT:    flw ft1, 4(a1)
+; ILP32-LP64-NEXT:    flw ft2, 8(a1)
+; ILP32-LP64-NEXT:    flw ft3, 12(a1)
+; ILP32-LP64-NEXT:    flw ft4, 16(a1)
+; ILP32-LP64-NEXT:    flw ft5, 20(a1)
+; ILP32-LP64-NEXT:    flw ft6, 24(a1)
+; ILP32-LP64-NEXT:    flw ft7, 28(a1)
+; ILP32-LP64-NEXT:    flw fa0, 32(a1)
+; ILP32-LP64-NEXT:    flw fa1, 36(a1)
+; ILP32-LP64-NEXT:    flw fa2, 40(a1)
+; ILP32-LP64-NEXT:    flw fa3, 44(a1)
+; ILP32-LP64-NEXT:    flw fa4, 48(a1)
+; ILP32-LP64-NEXT:    flw fa5, 52(a1)
+; ILP32-LP64-NEXT:    flw fa6, 56(a1)
+; ILP32-LP64-NEXT:    flw fa7, 60(a1)
+; ILP32-LP64-NEXT:    flw ft8, 64(a1)
+; ILP32-LP64-NEXT:    flw ft9, 68(a1)
+; ILP32-LP64-NEXT:    flw ft10, 72(a1)
+; ILP32-LP64-NEXT:    flw ft11, 76(a1)
+; ILP32-LP64-NEXT:    flw fs0, 80(a1)
+; ILP32-LP64-NEXT:    flw fs1, 84(a1)
+; ILP32-LP64-NEXT:    flw fs2, 88(a1)
+; ILP32-LP64-NEXT:    flw fs3, 92(a1)
+; ILP32-LP64-NEXT:    flw fs4, 96(a1)
+; ILP32-LP64-NEXT:    flw fs5, 100(a1)
+; ILP32-LP64-NEXT:    flw fs6, 104(a1)
+; ILP32-LP64-NEXT:    flw fs7, 108(a1)
+; ILP32-LP64-NEXT:    flw fs8, 112(a1)
+; ILP32-LP64-NEXT:    flw fs9, 116(a1)
+; ILP32-LP64-NEXT:    flw fs10, 120(a1)
+; ILP32-LP64-NEXT:    flw fs11, 124(a1)
+; ILP32-LP64-NEXT:    fsw fs11, 124(a1)
+; ILP32-LP64-NEXT:    fsw fs10, 120(a1)
+; ILP32-LP64-NEXT:    fsw fs9, 116(a1)
+; ILP32-LP64-NEXT:    fsw fs8, 112(a1)
+; ILP32-LP64-NEXT:    fsw fs7, 108(a1)
+; ILP32-LP64-NEXT:    fsw fs6, 104(a1)
+; ILP32-LP64-NEXT:    fsw fs5, 100(a1)
+; ILP32-LP64-NEXT:    fsw fs4, 96(a1)
+; ILP32-LP64-NEXT:    fsw fs3, 92(a1)
+; ILP32-LP64-NEXT:    fsw fs2, 88(a1)
+; ILP32-LP64-NEXT:    fsw fs1, 84(a1)
+; ILP32-LP64-NEXT:    fsw fs0, 80(a1)
+; ILP32-LP64-NEXT:    fsw ft11, 76(a1)
+; ILP32-LP64-NEXT:    fsw ft10, 72(a1)
+; ILP32-LP64-NEXT:    fsw ft9, 68(a1)
+; ILP32-LP64-NEXT:    fsw ft8, 64(a1)
+; ILP32-LP64-NEXT:    fsw fa7, 60(a1)
+; ILP32-LP64-NEXT:    fsw fa6, 56(a1)
+; ILP32-LP64-NEXT:    fsw fa5, 52(a1)
+; ILP32-LP64-NEXT:    fsw fa4, 48(a1)
+; ILP32-LP64-NEXT:    fsw fa3, 44(a1)
+; ILP32-LP64-NEXT:    fsw fa2, 40(a1)
+; ILP32-LP64-NEXT:    fsw fa1, 36(a1)
+; ILP32-LP64-NEXT:    fsw fa0, 32(a1)
+; ILP32-LP64-NEXT:    fsw ft7, 28(a1)
+; ILP32-LP64-NEXT:    fsw ft6, 24(a1)
+; ILP32-LP64-NEXT:    fsw ft5, 20(a1)
+; ILP32-LP64-NEXT:    fsw ft4, 16(a1)
+; ILP32-LP64-NEXT:    fsw ft3, 12(a1)
+; ILP32-LP64-NEXT:    fsw ft2, 8(a1)
+; ILP32-LP64-NEXT:    fsw ft1, 4(a1)
+; ILP32-LP64-NEXT:    fsw ft0, %lo(var)(a0)
+; ILP32-LP64-NEXT:    ret
+  %val = load [32 x float], [32 x float]* @var
+  store volatile [32 x float] %val, [32 x float]* @var
+  ret void
+}
diff --git a/test/CodeGen/RISCV/callee-saved-fpr64s.ll b/test/CodeGen/RISCV/callee-saved-fpr64s.ll
new file mode 100644
index 0000000..17126bd
--- /dev/null
+++ b/test/CodeGen/RISCV/callee-saved-fpr64s.ll
@@ -0,0 +1,84 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s -check-prefix=ILP32-LP64
+; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s -check-prefix=ILP32-LP64
+
+@var = global [32 x double] zeroinitializer
+
+; All floating point registers are temporaries for the ilp32 and lp64 ABIs.
+
+define void @foo() {
+; ILP32-LP64-LABEL: foo:
+; ILP32-LP64:       # %bb.0:
+; ILP32-LP64-NEXT:    lui a0, %hi(var)
+; ILP32-LP64-NEXT:    addi a1, a0, %lo(var)
+; ILP32-LP64-NEXT:    fld ft0, %lo(var)(a0)
+; ILP32-LP64-NEXT:    fld ft1, 8(a1)
+; ILP32-LP64-NEXT:    fld ft2, 16(a1)
+; ILP32-LP64-NEXT:    fld ft3, 24(a1)
+; ILP32-LP64-NEXT:    fld ft4, 32(a1)
+; ILP32-LP64-NEXT:    fld ft5, 40(a1)
+; ILP32-LP64-NEXT:    fld ft6, 48(a1)
+; ILP32-LP64-NEXT:    fld ft7, 56(a1)
+; ILP32-LP64-NEXT:    fld fa0, 64(a1)
+; ILP32-LP64-NEXT:    fld fa1, 72(a1)
+; ILP32-LP64-NEXT:    fld fa2, 80(a1)
+; ILP32-LP64-NEXT:    fld fa3, 88(a1)
+; ILP32-LP64-NEXT:    fld fa4, 96(a1)
+; ILP32-LP64-NEXT:    fld fa5, 104(a1)
+; ILP32-LP64-NEXT:    fld fa6, 112(a1)
+; ILP32-LP64-NEXT:    fld fa7, 120(a1)
+; ILP32-LP64-NEXT:    fld ft8, 128(a1)
+; ILP32-LP64-NEXT:    fld ft9, 136(a1)
+; ILP32-LP64-NEXT:    fld ft10, 144(a1)
+; ILP32-LP64-NEXT:    fld ft11, 152(a1)
+; ILP32-LP64-NEXT:    fld fs0, 160(a1)
+; ILP32-LP64-NEXT:    fld fs1, 168(a1)
+; ILP32-LP64-NEXT:    fld fs2, 176(a1)
+; ILP32-LP64-NEXT:    fld fs3, 184(a1)
+; ILP32-LP64-NEXT:    fld fs4, 192(a1)
+; ILP32-LP64-NEXT:    fld fs5, 200(a1)
+; ILP32-LP64-NEXT:    fld fs6, 208(a1)
+; ILP32-LP64-NEXT:    fld fs7, 216(a1)
+; ILP32-LP64-NEXT:    fld fs8, 224(a1)
+; ILP32-LP64-NEXT:    fld fs9, 232(a1)
+; ILP32-LP64-NEXT:    fld fs10, 240(a1)
+; ILP32-LP64-NEXT:    fld fs11, 248(a1)
+; ILP32-LP64-NEXT:    fsd fs11, 248(a1)
+; ILP32-LP64-NEXT:    fsd fs10, 240(a1)
+; ILP32-LP64-NEXT:    fsd fs9, 232(a1)
+; ILP32-LP64-NEXT:    fsd fs8, 224(a1)
+; ILP32-LP64-NEXT:    fsd fs7, 216(a1)
+; ILP32-LP64-NEXT:    fsd fs6, 208(a1)
+; ILP32-LP64-NEXT:    fsd fs5, 200(a1)
+; ILP32-LP64-NEXT:    fsd fs4, 192(a1)
+; ILP32-LP64-NEXT:    fsd fs3, 184(a1)
+; ILP32-LP64-NEXT:    fsd fs2, 176(a1)
+; ILP32-LP64-NEXT:    fsd fs1, 168(a1)
+; ILP32-LP64-NEXT:    fsd fs0, 160(a1)
+; ILP32-LP64-NEXT:    fsd ft11, 152(a1)
+; ILP32-LP64-NEXT:    fsd ft10, 144(a1)
+; ILP32-LP64-NEXT:    fsd ft9, 136(a1)
+; ILP32-LP64-NEXT:    fsd ft8, 128(a1)
+; ILP32-LP64-NEXT:    fsd fa7, 120(a1)
+; ILP32-LP64-NEXT:    fsd fa6, 112(a1)
+; ILP32-LP64-NEXT:    fsd fa5, 104(a1)
+; ILP32-LP64-NEXT:    fsd fa4, 96(a1)
+; ILP32-LP64-NEXT:    fsd fa3, 88(a1)
+; ILP32-LP64-NEXT:    fsd fa2, 80(a1)
+; ILP32-LP64-NEXT:    fsd fa1, 72(a1)
+; ILP32-LP64-NEXT:    fsd fa0, 64(a1)
+; ILP32-LP64-NEXT:    fsd ft7, 56(a1)
+; ILP32-LP64-NEXT:    fsd ft6, 48(a1)
+; ILP32-LP64-NEXT:    fsd ft5, 40(a1)
+; ILP32-LP64-NEXT:    fsd ft4, 32(a1)
+; ILP32-LP64-NEXT:    fsd ft3, 24(a1)
+; ILP32-LP64-NEXT:    fsd ft2, 16(a1)
+; ILP32-LP64-NEXT:    fsd ft1, 8(a1)
+; ILP32-LP64-NEXT:    fsd ft0, %lo(var)(a0)
+; ILP32-LP64-NEXT:    ret
+  %val = load [32 x double], [32 x double]* @var
+  store volatile [32 x double] %val, [32 x double]* @var
+  ret void
+}
diff --git a/test/CodeGen/RISCV/callee-saved-gprs.ll b/test/CodeGen/RISCV/callee-saved-gprs.ll
new file mode 100644
index 0000000..eb68449
--- /dev/null
+++ b/test/CodeGen/RISCV/callee-saved-gprs.ll
@@ -0,0 +1,91 @@
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s -check-prefix=RV32I
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all < %s \
+; RUN:   | FileCheck %s -check-prefix=RV32I-WITH-FP
+; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s -check-prefix=RV64I
+; RUN: llc -mtriple=riscv64 -verify-machineinstrs -frame-pointer=all < %s \
+; RUN:   | FileCheck %s -check-prefix=RV64I-WITH-FP
+
+@var = global [32 x i32] zeroinitializer
+
+; TODO: s0 need not be reserved if the function doesn't use a framepointer.
+
+define void @foo() {
+; RV32I-LABEL: foo:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    addi sp, sp, -80
+; RV32I-NEXT:    sw s1, 76(sp)
+; RV32I-NEXT:    sw s2, 72(sp)
+; RV32I-NEXT:    sw s3, 68(sp)
+; RV32I-NEXT:    sw s4, 64(sp)
+; RV32I-NEXT:    sw s5, 60(sp)
+; RV32I-NEXT:    sw s6, 56(sp)
+; RV32I-NEXT:    sw s7, 52(sp)
+; RV32I-NEXT:    sw s8, 48(sp)
+; RV32I-NEXT:    sw s9, 44(sp)
+; RV32I-NEXT:    sw s10, 40(sp)
+; RV32I-NEXT:    sw s11, 36(sp)
+; RV32I-NEXT:    lui a0, %hi(var)
+; RV32I-NEXT:    addi a1, a0, %lo(var)
+;
+; RV32I-WITH-FP-LABEL: foo:
+; RV32I-WITH-FP:       # %bb.0:
+; RV32I-WITH-FP-NEXT:    addi sp, sp, -80
+; RV32I-WITH-FP-NEXT:    sw ra, 76(sp)
+; RV32I-WITH-FP-NEXT:    sw s0, 72(sp)
+; RV32I-WITH-FP-NEXT:    sw s1, 68(sp)
+; RV32I-WITH-FP-NEXT:    sw s2, 64(sp)
+; RV32I-WITH-FP-NEXT:    sw s3, 60(sp)
+; RV32I-WITH-FP-NEXT:    sw s4, 56(sp)
+; RV32I-WITH-FP-NEXT:    sw s5, 52(sp)
+; RV32I-WITH-FP-NEXT:    sw s6, 48(sp)
+; RV32I-WITH-FP-NEXT:    sw s7, 44(sp)
+; RV32I-WITH-FP-NEXT:    sw s8, 40(sp)
+; RV32I-WITH-FP-NEXT:    sw s9, 36(sp)
+; RV32I-WITH-FP-NEXT:    sw s10, 32(sp)
+; RV32I-WITH-FP-NEXT:    sw s11, 28(sp)
+; RV32I-WITH-FP-NEXT:    addi s0, sp, 80
+; RV32I-WITH-FP-NEXT:    lui a0, %hi(var)
+; RV32I-WITH-FP-NEXT:    addi a1, a0, %lo(var)
+;
+; RV64I-LABEL: foo:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    addi sp, sp, -144
+; RV64I-NEXT:    sd s1, 136(sp)
+; RV64I-NEXT:    sd s2, 128(sp)
+; RV64I-NEXT:    sd s3, 120(sp)
+; RV64I-NEXT:    sd s4, 112(sp)
+; RV64I-NEXT:    sd s5, 104(sp)
+; RV64I-NEXT:    sd s6, 96(sp)
+; RV64I-NEXT:    sd s7, 88(sp)
+; RV64I-NEXT:    sd s8, 80(sp)
+; RV64I-NEXT:    sd s9, 72(sp)
+; RV64I-NEXT:    sd s10, 64(sp)
+; RV64I-NEXT:    sd s11, 56(sp)
+; RV64I-NEXT:    lui a0, %hi(var)
+; RV64I-NEXT:    addi a1, a0, %lo(var)
+;
+; RV64I-WITH-FP-LABEL: foo:
+; RV64I-WITH-FP:       # %bb.0:
+; RV64I-WITH-FP-NEXT:    addi sp, sp, -160
+; RV64I-WITH-FP-NEXT:    sd ra, 152(sp)
+; RV64I-WITH-FP-NEXT:    sd s0, 144(sp)
+; RV64I-WITH-FP-NEXT:    sd s1, 136(sp)
+; RV64I-WITH-FP-NEXT:    sd s2, 128(sp)
+; RV64I-WITH-FP-NEXT:    sd s3, 120(sp)
+; RV64I-WITH-FP-NEXT:    sd s4, 112(sp)
+; RV64I-WITH-FP-NEXT:    sd s5, 104(sp)
+; RV64I-WITH-FP-NEXT:    sd s6, 96(sp)
+; RV64I-WITH-FP-NEXT:    sd s7, 88(sp)
+; RV64I-WITH-FP-NEXT:    sd s8, 80(sp)
+; RV64I-WITH-FP-NEXT:    sd s9, 72(sp)
+; RV64I-WITH-FP-NEXT:    sd s10, 64(sp)
+; RV64I-WITH-FP-NEXT:    sd s11, 56(sp)
+; RV64I-WITH-FP-NEXT:    addi s0, sp, 160
+; RV64I-WITH-FP-NEXT:    lui a0, %hi(var)
+; RV64I-WITH-FP-NEXT:    addi a1, a0, %lo(var)
+  %val = load [32 x i32], [32 x i32]* @var
+  store volatile [32 x i32] %val, [32 x i32]* @var
+  ret void
+}