summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/CodeGen')
-rw-r--r--llvm/test/CodeGen/RISCV/callee-saved-fpr32s.ll107
-rw-r--r--llvm/test/CodeGen/RISCV/callee-saved-fpr64s.ll58
-rw-r--r--llvm/test/CodeGen/RISCV/callee-saved-gprs.ll12
-rw-r--r--llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-common.ll6
-rw-r--r--llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll12
-rw-r--r--llvm/test/CodeGen/RISCV/calling-conv-ilp32d.ll294
-rw-r--r--llvm/test/CodeGen/RISCV/calling-conv-ilp32f-ilp32d-common.ll221
-rw-r--r--llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-common.ll3
-rw-r--r--llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll6
-rw-r--r--llvm/test/CodeGen/RISCV/target-abi-valid.ll24
-rw-r--r--llvm/test/CodeGen/RISCV/vararg.ll20
11 files changed, 741 insertions, 22 deletions
diff --git a/llvm/test/CodeGen/RISCV/callee-saved-fpr32s.ll b/llvm/test/CodeGen/RISCV/callee-saved-fpr32s.ll
index 41bac2aa087..f40faf59b7a 100644
--- a/llvm/test/CodeGen/RISCV/callee-saved-fpr32s.ll
+++ b/llvm/test/CodeGen/RISCV/callee-saved-fpr32s.ll
@@ -2,10 +2,19 @@
; RUN: | FileCheck %s -check-prefix=ILP32-LP64
; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
; RUN: | FileCheck %s -check-prefix=ILP32-LP64
+; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=ILP32F-LP64F
+; RUN: llc -mtriple=riscv64 -mattr=+f -target-abi lp64f -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=ILP32F-LP64F
+; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=ILP32D-LP64D
+; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64d -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=ILP32D-LP64D
@var = global [32 x float] zeroinitializer
; All floating point registers are temporaries for the ilp32 and lp64 ABIs.
+; fs0-fs11 are callee-saved for the ilp32f, ilp32d, lp64f, and lp64d ABIs.
; This function tests that RISCVRegisterInfo::getCalleeSavedRegs returns
; something appropriate.
@@ -80,6 +89,42 @@ define void @callee() {
; ILP32-LP64-NEXT: fsw ft1, 4(a1)
; ILP32-LP64-NEXT: fsw ft0, %lo(var)(a0)
; ILP32-LP64-NEXT: ret
+;
+; ILP32F-LP64F-LABEL: callee:
+; ILP32F-LP64F: # %bb.0:
+; ILP32F-LP64F-NEXT: addi sp, sp, -48
+; ILP32F-LP64F-NEXT: fsw fs0, 44(sp)
+; ILP32F-LP64F-NEXT: fsw fs1, 40(sp)
+; ILP32F-LP64F-NEXT: fsw fs2, 36(sp)
+; ILP32F-LP64F-NEXT: fsw fs3, 32(sp)
+; ILP32F-LP64F-NEXT: fsw fs4, 28(sp)
+; ILP32F-LP64F-NEXT: fsw fs5, 24(sp)
+; ILP32F-LP64F-NEXT: fsw fs6, 20(sp)
+; ILP32F-LP64F-NEXT: fsw fs7, 16(sp)
+; ILP32F-LP64F-NEXT: fsw fs8, 12(sp)
+; ILP32F-LP64F-NEXT: fsw fs9, 8(sp)
+; ILP32F-LP64F-NEXT: fsw fs10, 4(sp)
+; ILP32F-LP64F-NEXT: fsw fs11, 0(sp)
+; ILP32F-LP64F-NEXT: lui a0, %hi(var)
+; ILP32F-LP64F-NEXT: addi a1, a0, %lo(var)
+;
+; ILP32D-LP64D-LABEL: callee:
+; ILP32D-LP64D: # %bb.0:
+; ILP32D-LP64D-NEXT: addi sp, sp, -96
+; ILP32D-LP64D-NEXT: fsd fs0, 88(sp)
+; ILP32D-LP64D-NEXT: fsd fs1, 80(sp)
+; ILP32D-LP64D-NEXT: fsd fs2, 72(sp)
+; ILP32D-LP64D-NEXT: fsd fs3, 64(sp)
+; ILP32D-LP64D-NEXT: fsd fs4, 56(sp)
+; ILP32D-LP64D-NEXT: fsd fs5, 48(sp)
+; ILP32D-LP64D-NEXT: fsd fs6, 40(sp)
+; ILP32D-LP64D-NEXT: fsd fs7, 32(sp)
+; ILP32D-LP64D-NEXT: fsd fs8, 24(sp)
+; ILP32D-LP64D-NEXT: fsd fs9, 16(sp)
+; ILP32D-LP64D-NEXT: fsd fs10, 8(sp)
+; ILP32D-LP64D-NEXT: fsd fs11, 0(sp)
+; ILP32D-LP64D-NEXT: lui a0, %hi(var)
+; ILP32D-LP64D-NEXT: addi a1, a0, %lo(var)
%val = load [32 x float], [32 x float]* @var
store volatile [32 x float] %val, [32 x float]* @var
ret void
@@ -89,17 +134,75 @@ define void @callee() {
; something appropriate.
;
; For the soft float ABIs, no floating point registers are preserved, and
-; codegen will use only ft0 in the body of caller.
+; codegen will use only ft0 in the body of caller. For the 'f' and 'd ABIs,
+; fs0-fs11 are preserved across calls.
define void @caller() {
; ILP32-LP64-LABEL: caller:
; ILP32-LP64-NOT: ft{{[1-9][0-9]*}}
; ILP32-LP64-NOT: fs{{[0-9]+}}
; ILP32-LP64-NOT: fa{{[0-9]+}}
-; ILP32-LP64: ret
+; ILP32-LP64: call callee
; ILP32-LP64-NOT: ft{{[1-9][0-9]*}}
; ILP32-LP64-NOT: fs{{[0-9]+}}
; ILP32-LP64-NOT: fa{{[0-9]+}}
+; ILP32-LP64: ret
+;
+; ILP32F-LP64F-LABEL: caller:
+; ILP32F-LP64F: flw fs8, 80(s1)
+; ILP32F-LP64F-NEXT: flw fs9, 84(s1)
+; ILP32F-LP64F-NEXT: flw fs10, 88(s1)
+; ILP32F-LP64F-NEXT: flw fs11, 92(s1)
+; ILP32F-LP64F-NEXT: flw fs0, 96(s1)
+; ILP32F-LP64F-NEXT: flw fs1, 100(s1)
+; ILP32F-LP64F-NEXT: flw fs2, 104(s1)
+; ILP32F-LP64F-NEXT: flw fs3, 108(s1)
+; ILP32F-LP64F-NEXT: flw fs4, 112(s1)
+; ILP32F-LP64F-NEXT: flw fs5, 116(s1)
+; ILP32F-LP64F-NEXT: flw fs6, 120(s1)
+; ILP32F-LP64F-NEXT: flw fs7, 124(s1)
+; ILP32F-LP64F-NEXT: call callee
+; ILP32F-LP64F-NEXT: fsw fs7, 124(s1)
+; ILP32F-LP64F-NEXT: fsw fs6, 120(s1)
+; ILP32F-LP64F-NEXT: fsw fs5, 116(s1)
+; ILP32F-LP64F-NEXT: fsw fs4, 112(s1)
+; ILP32F-LP64F-NEXT: fsw fs3, 108(s1)
+; ILP32F-LP64F-NEXT: fsw fs2, 104(s1)
+; ILP32F-LP64F-NEXT: fsw fs1, 100(s1)
+; ILP32F-LP64F-NEXT: fsw fs0, 96(s1)
+; ILP32F-LP64F-NEXT: fsw fs11, 92(s1)
+; ILP32F-LP64F-NEXT: fsw fs10, 88(s1)
+; ILP32F-LP64F-NEXT: fsw fs9, 84(s1)
+; ILP32F-LP64F-NEXT: fsw fs8, 80(s1)
+; ILP32F-LP64F-NEXT: lw ft0, {{[0-9]+}}(sp)
+;
+; ILP32D-LP64D-LABEL: caller:
+; ILP32D-LP64D: flw fs8, 80(s1)
+; ILP32D-LP64D-NEXT: flw fs9, 84(s1)
+; ILP32D-LP64D-NEXT: flw fs10, 88(s1)
+; ILP32D-LP64D-NEXT: flw fs11, 92(s1)
+; ILP32D-LP64D-NEXT: flw fs0, 96(s1)
+; ILP32D-LP64D-NEXT: flw fs1, 100(s1)
+; ILP32D-LP64D-NEXT: flw fs2, 104(s1)
+; ILP32D-LP64D-NEXT: flw fs3, 108(s1)
+; ILP32D-LP64D-NEXT: flw fs4, 112(s1)
+; ILP32D-LP64D-NEXT: flw fs5, 116(s1)
+; ILP32D-LP64D-NEXT: flw fs6, 120(s1)
+; ILP32D-LP64D-NEXT: flw fs7, 124(s1)
+; ILP32D-LP64D-NEXT: call callee
+; ILP32D-LP64D-NEXT: fsw fs7, 124(s1)
+; ILP32D-LP64D-NEXT: fsw fs6, 120(s1)
+; ILP32D-LP64D-NEXT: fsw fs5, 116(s1)
+; ILP32D-LP64D-NEXT: fsw fs4, 112(s1)
+; ILP32D-LP64D-NEXT: fsw fs3, 108(s1)
+; ILP32D-LP64D-NEXT: fsw fs2, 104(s1)
+; ILP32D-LP64D-NEXT: fsw fs1, 100(s1)
+; ILP32D-LP64D-NEXT: fsw fs0, 96(s1)
+; ILP32D-LP64D-NEXT: fsw fs11, 92(s1)
+; ILP32D-LP64D-NEXT: fsw fs10, 88(s1)
+; ILP32D-LP64D-NEXT: fsw fs9, 84(s1)
+; ILP32D-LP64D-NEXT: fsw fs8, 80(s1)
+; ILP32D-LP64D-NEXT: flw ft0, {{[0-9]+}}(sp)
%val = load [32 x float], [32 x float]* @var
call void @callee()
store volatile [32 x float] %val, [32 x float]* @var
diff --git a/llvm/test/CodeGen/RISCV/callee-saved-fpr64s.ll b/llvm/test/CodeGen/RISCV/callee-saved-fpr64s.ll
index d8571baca5d..b8b4729af7f 100644
--- a/llvm/test/CodeGen/RISCV/callee-saved-fpr64s.ll
+++ b/llvm/test/CodeGen/RISCV/callee-saved-fpr64s.ll
@@ -1,12 +1,16 @@
-; 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
+; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=ILP32D-LP64D
+; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64d -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=ILP32D-LP64D
@var = global [32 x double] zeroinitializer
; All floating point registers are temporaries for the ilp32 and lp64 ABIs.
+; fs0-fs11 are callee-saved for the ilp32f, ilp32d, lp64f, and lp64d ABIs.
; This function tests that RISCVRegisterInfo::getCalleeSavedRegs returns
; something appropriate.
@@ -81,6 +85,24 @@ define void @callee() {
; ILP32-LP64-NEXT: fsd ft1, 8(a1)
; ILP32-LP64-NEXT: fsd ft0, %lo(var)(a0)
; ILP32-LP64-NEXT: ret
+;
+; ILP32D-LP64D-LABEL: callee:
+; ILP32D-LP64D: # %bb.0:
+; ILP32D-LP64D-NEXT: addi sp, sp, -96
+; ILP32D-LP64D-NEXT: fsd fs0, 88(sp)
+; ILP32D-LP64D-NEXT: fsd fs1, 80(sp)
+; ILP32D-LP64D-NEXT: fsd fs2, 72(sp)
+; ILP32D-LP64D-NEXT: fsd fs3, 64(sp)
+; ILP32D-LP64D-NEXT: fsd fs4, 56(sp)
+; ILP32D-LP64D-NEXT: fsd fs5, 48(sp)
+; ILP32D-LP64D-NEXT: fsd fs6, 40(sp)
+; ILP32D-LP64D-NEXT: fsd fs7, 32(sp)
+; ILP32D-LP64D-NEXT: fsd fs8, 24(sp)
+; ILP32D-LP64D-NEXT: fsd fs9, 16(sp)
+; ILP32D-LP64D-NEXT: fsd fs10, 8(sp)
+; ILP32D-LP64D-NEXT: fsd fs11, 0(sp)
+; ILP32D-LP64D-NEXT: lui a0, %hi(var)
+; ILP32D-LP64D-NEXT: addi a1, a0, %lo(var)
%val = load [32 x double], [32 x double]* @var
store volatile [32 x double] %val, [32 x double]* @var
ret void
@@ -90,17 +112,47 @@ define void @callee() {
; something appropriate.
;
; For the soft float ABIs, no floating point registers are preserved, and
-; codegen will use only ft0 in the body of caller.
+; codegen will use only ft0 in the body of caller. For the 'f' and 'd ABIs,
+; fs0-fs11 are preserved across calls.
define void @caller() {
; ILP32-LP64-LABEL: caller:
; ILP32-LP64-NOT: ft{{[1-9][0-9]*}}
; ILP32-LP64-NOT: fs{{[0-9]+}}
; ILP32-LP64-NOT: fa{{[0-9]+}}
-; ILP32-LP64: ret
+; ILP32-LP64: call callee
; ILP32-LP64-NOT: ft{{[1-9][0-9]*}}
; ILP32-LP64-NOT: fs{{[0-9]+}}
; ILP32-LP64-NOT: fa{{[0-9]+}}
+; ILP32-LP64: ret
+;
+; ILP32F-LP64D-LABEL: caller:
+; ILP32D-LP64D: fld fs8, 160(s1)
+; ILP32D-LP64D-NEXT: fld fs9, 168(s1)
+; ILP32D-LP64D-NEXT: fld fs10, 176(s1)
+; ILP32D-LP64D-NEXT: fld fs11, 184(s1)
+; ILP32D-LP64D-NEXT: fld fs0, 192(s1)
+; ILP32D-LP64D-NEXT: fld fs1, 200(s1)
+; ILP32D-LP64D-NEXT: fld fs2, 208(s1)
+; ILP32D-LP64D-NEXT: fld fs3, 216(s1)
+; ILP32D-LP64D-NEXT: fld fs4, 224(s1)
+; ILP32D-LP64D-NEXT: fld fs5, 232(s1)
+; ILP32D-LP64D-NEXT: fld fs6, 240(s1)
+; ILP32D-LP64D-NEXT: fld fs7, 248(s1)
+; ILP32D-LP64D-NEXT: call callee
+; ILP32D-LP64D-NEXT: fsd fs7, 248(s1)
+; ILP32D-LP64D-NEXT: fsd fs6, 240(s1)
+; ILP32D-LP64D-NEXT: fsd fs5, 232(s1)
+; ILP32D-LP64D-NEXT: fsd fs4, 224(s1)
+; ILP32D-LP64D-NEXT: fsd fs3, 216(s1)
+; ILP32D-LP64D-NEXT: fsd fs2, 208(s1)
+; ILP32D-LP64D-NEXT: fsd fs1, 200(s1)
+; ILP32D-LP64D-NEXT: fsd fs0, 192(s1)
+; ILP32D-LP64D-NEXT: fsd fs11, 184(s1)
+; ILP32D-LP64D-NEXT: fsd fs10, 176(s1)
+; ILP32D-LP64D-NEXT: fsd fs9, 168(s1)
+; ILP32D-LP64D-NEXT: fsd fs8, 160(s1)
+; ILP32D-LP64D-NEXT: fld ft0, {{[0-9]+}}(sp)
%val = load [32 x double], [32 x double]* @var
call void @callee()
store volatile [32 x double] %val, [32 x double]* @var
diff --git a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
index b10b5a6c77a..e8b83151885 100644
--- a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
+++ b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
@@ -1,9 +1,21 @@
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
; RUN: | FileCheck %s -check-prefix=RV32I
+; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=RV32I
+; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32f -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=RV32I
+; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d -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 -mattr=+f -target-abi ilp32f -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=RV64I
+; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi ilp32f -verify-machineinstrs < %s \
+; RUN: | FileCheck %s -check-prefix=RV64I
+; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi ilp32d -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
diff --git a/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-common.ll b/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-common.ll
index f831cdae8ca..c93edcaec25 100644
--- a/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-common.ll
+++ b/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-common.ll
@@ -1,8 +1,14 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s
+; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f \
+; RUN: -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s
; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all < %s \
; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all \
+; RUN: -mattr=+f -target-abi ilp32f < %s \
+; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
; This file contains tests that should have identical output for the ilp32,
; and ilp32f. As well as calling convention details, we check that
diff --git a/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll b/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll
index f499ca8a0e9..10b0d54627d 100644
--- a/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll
+++ b/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll
@@ -1,8 +1,20 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s
+; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f \
+; RUN: -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s
+; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d \
+; RUN: -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s
; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all < %s \
; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all \
+; RUN: -mattr=+f -target-abi ilp32f < %s \
+; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all \
+; RUN: -mattr=+d -target-abi ilp32d < %s \
+; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
; This file contains tests that should have identical output for the ilp32,
; ilp32f, and ilp32d ABIs. i.e. where no arguments are passed according to
diff --git a/llvm/test/CodeGen/RISCV/calling-conv-ilp32d.ll b/llvm/test/CodeGen/RISCV/calling-conv-ilp32d.ll
new file mode 100644
index 00000000000..37dfa7bf9c8
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/calling-conv-ilp32d.ll
@@ -0,0 +1,294 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+d \
+; RUN: -target-abi ilp32d < %s \
+; RUN: | FileCheck -check-prefix=RV32-ILP32D %s
+
+; This file contains tests that will have differing output for the ilp32 and
+; ilp32f ABIs.
+
+define i32 @callee_double_in_fpr(i32 %a, double %b) nounwind {
+; RV32-ILP32D-LABEL: callee_double_in_fpr:
+; RV32-ILP32D: # %bb.0:
+; RV32-ILP32D-NEXT: fcvt.w.d a1, fa0, rtz
+; RV32-ILP32D-NEXT: add a0, a0, a1
+; RV32-ILP32D-NEXT: ret
+ %b_fptosi = fptosi double %b to i32
+ %1 = add i32 %a, %b_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_double_in_fpr() nounwind {
+; RV32-ILP32D-LABEL: caller_double_in_fpr:
+; RV32-ILP32D: # %bb.0:
+; RV32-ILP32D-NEXT: addi sp, sp, -16
+; RV32-ILP32D-NEXT: sw ra, 12(sp)
+; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI1_0)
+; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI1_0)
+; RV32-ILP32D-NEXT: fld fa0, 0(a0)
+; RV32-ILP32D-NEXT: addi a0, zero, 1
+; RV32-ILP32D-NEXT: call callee_double_in_fpr
+; RV32-ILP32D-NEXT: lw ra, 12(sp)
+; RV32-ILP32D-NEXT: addi sp, sp, 16
+; RV32-ILP32D-NEXT: ret
+ %1 = call i32 @callee_double_in_fpr(i32 1, double 2.0)
+ ret i32 %1
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_double_in_fpr_exhausted_gprs(i64 %a, i64 %b, i64 %c, i64 %d, i32 %e, double %f) nounwind {
+; RV32-ILP32D-LABEL: callee_double_in_fpr_exhausted_gprs:
+; RV32-ILP32D: # %bb.0:
+; RV32-ILP32D-NEXT: fcvt.w.d a0, fa0, rtz
+; RV32-ILP32D-NEXT: lw a1, 0(sp)
+; RV32-ILP32D-NEXT: add a0, a1, a0
+; RV32-ILP32D-NEXT: ret
+ %f_fptosi = fptosi double %f to i32
+ %1 = add i32 %e, %f_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_double_in_fpr_exhausted_gprs() nounwind {
+; RV32-ILP32D-LABEL: caller_double_in_fpr_exhausted_gprs:
+; RV32-ILP32D: # %bb.0:
+; RV32-ILP32D-NEXT: addi sp, sp, -16
+; RV32-ILP32D-NEXT: sw ra, 12(sp)
+; RV32-ILP32D-NEXT: addi a0, zero, 5
+; RV32-ILP32D-NEXT: sw a0, 0(sp)
+; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI3_0)
+; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI3_0)
+; RV32-ILP32D-NEXT: fld fa0, 0(a0)
+; RV32-ILP32D-NEXT: addi a0, zero, 1
+; RV32-ILP32D-NEXT: mv a1, zero
+; RV32-ILP32D-NEXT: addi a2, zero, 2
+; RV32-ILP32D-NEXT: mv a3, zero
+; RV32-ILP32D-NEXT: addi a4, zero, 3
+; RV32-ILP32D-NEXT: mv a5, zero
+; RV32-ILP32D-NEXT: addi a6, zero, 4
+; RV32-ILP32D-NEXT: mv a7, zero
+; RV32-ILP32D-NEXT: call callee_double_in_fpr_exhausted_gprs
+; RV32-ILP32D-NEXT: lw ra, 12(sp)
+; RV32-ILP32D-NEXT: addi sp, sp, 16
+; RV32-ILP32D-NEXT: ret
+ %1 = call i32 @callee_double_in_fpr_exhausted_gprs(
+ i64 1, i64 2, i64 3, i64 4, i32 5, double 6.0)
+ ret i32 %1
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_double_in_gpr_exhausted_fprs(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i) nounwind {
+; RV32-ILP32D-LABEL: callee_double_in_gpr_exhausted_fprs:
+; RV32-ILP32D: # %bb.0:
+; RV32-ILP32D-NEXT: addi sp, sp, -16
+; RV32-ILP32D-NEXT: sw a0, 8(sp)
+; RV32-ILP32D-NEXT: sw a1, 12(sp)
+; RV32-ILP32D-NEXT: fld ft0, 8(sp)
+; RV32-ILP32D-NEXT: fcvt.w.d a0, ft0, rtz
+; RV32-ILP32D-NEXT: fcvt.w.d a1, fa7, rtz
+; RV32-ILP32D-NEXT: add a0, a1, a0
+; RV32-ILP32D-NEXT: addi sp, sp, 16
+; RV32-ILP32D-NEXT: ret
+ %h_fptosi = fptosi double %h to i32
+ %i_fptosi = fptosi double %i to i32
+ %1 = add i32 %h_fptosi, %i_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_double_in_gpr_exhausted_fprs() nounwind {
+; RV32-ILP32D-LABEL: caller_double_in_gpr_exhausted_fprs:
+; RV32-ILP32D: # %bb.0:
+; RV32-ILP32D-NEXT: addi sp, sp, -16
+; RV32-ILP32D-NEXT: sw ra, 12(sp)
+; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI5_0)
+; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI5_0)
+; RV32-ILP32D-NEXT: lui a1, %hi(.LCPI5_1)
+; RV32-ILP32D-NEXT: addi a1, a1, %lo(.LCPI5_1)
+; RV32-ILP32D-NEXT: lui a2, %hi(.LCPI5_2)
+; RV32-ILP32D-NEXT: addi a2, a2, %lo(.LCPI5_2)
+; RV32-ILP32D-NEXT: lui a3, %hi(.LCPI5_3)
+; RV32-ILP32D-NEXT: addi a3, a3, %lo(.LCPI5_3)
+; RV32-ILP32D-NEXT: lui a4, %hi(.LCPI5_4)
+; RV32-ILP32D-NEXT: addi a4, a4, %lo(.LCPI5_4)
+; RV32-ILP32D-NEXT: lui a5, %hi(.LCPI5_5)
+; RV32-ILP32D-NEXT: addi a5, a5, %lo(.LCPI5_5)
+; RV32-ILP32D-NEXT: fld fa0, 0(a5)
+; RV32-ILP32D-NEXT: fld fa1, 0(a4)
+; RV32-ILP32D-NEXT: fld fa2, 0(a3)
+; RV32-ILP32D-NEXT: fld fa3, 0(a2)
+; RV32-ILP32D-NEXT: fld fa4, 0(a1)
+; RV32-ILP32D-NEXT: fld fa5, 0(a0)
+; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI5_6)
+; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI5_6)
+; RV32-ILP32D-NEXT: fld fa6, 0(a0)
+; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI5_7)
+; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI5_7)
+; RV32-ILP32D-NEXT: fld fa7, 0(a0)
+; RV32-ILP32D-NEXT: mv a0, zero
+; RV32-ILP32D-NEXT: lui a1, 262688
+; RV32-ILP32D-NEXT: call callee_double_in_gpr_exhausted_fprs
+; RV32-ILP32D-NEXT: lw ra, 12(sp)
+; RV32-ILP32D-NEXT: addi sp, sp, 16
+; RV32-ILP32D-NEXT: ret
+ %1 = call i32 @callee_double_in_gpr_exhausted_fprs(
+ double 1.0, double 2.0, double 3.0, double 4.0, double 5.0, double 6.0,
+ double 7.0, double 8.0, double 9.0)
+ ret i32 %1
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs(i64 %a, double %b, i64 %c, double %d, i64 %e, double %f, i32 %g, double %h, double %i, double %j, double %k, double %l, double %m) nounwind {
+; RV32-ILP32D-LABEL: callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs:
+; RV32-ILP32D: # %bb.0:
+; RV32-ILP32D-NEXT: addi sp, sp, -16
+; RV32-ILP32D-NEXT: lw a0, 16(sp)
+; RV32-ILP32D-NEXT: sw a7, 8(sp)
+; RV32-ILP32D-NEXT: sw a0, 12(sp)
+; RV32-ILP32D-NEXT: fld ft0, 8(sp)
+; RV32-ILP32D-NEXT: fcvt.w.d a0, ft0, rtz
+; RV32-ILP32D-NEXT: add a0, a6, a0
+; RV32-ILP32D-NEXT: addi sp, sp, 16
+; RV32-ILP32D-NEXT: ret
+ %m_fptosi = fptosi double %m to i32
+ %1 = add i32 %g, %m_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_double_in_gpr_and_stack_almost_exhausted_gprs_fprs() nounwind {
+; RV32-ILP32D-LABEL: caller_double_in_gpr_and_stack_almost_exhausted_gprs_fprs:
+; RV32-ILP32D: # %bb.0:
+; RV32-ILP32D-NEXT: addi sp, sp, -16
+; RV32-ILP32D-NEXT: sw ra, 12(sp)
+; RV32-ILP32D-NEXT: lui a0, 262816
+; RV32-ILP32D-NEXT: sw a0, 0(sp)
+; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI7_0)
+; RV32-ILP32D-NEXT: addi a6, a0, %lo(.LCPI7_0)
+; RV32-ILP32D-NEXT: lui a1, %hi(.LCPI7_1)
+; RV32-ILP32D-NEXT: addi a1, a1, %lo(.LCPI7_1)
+; RV32-ILP32D-NEXT: lui a2, %hi(.LCPI7_2)
+; RV32-ILP32D-NEXT: addi a2, a2, %lo(.LCPI7_2)
+; RV32-ILP32D-NEXT: lui a3, %hi(.LCPI7_3)
+; RV32-ILP32D-NEXT: addi a3, a3, %lo(.LCPI7_3)
+; RV32-ILP32D-NEXT: lui a4, %hi(.LCPI7_4)
+; RV32-ILP32D-NEXT: addi a4, a4, %lo(.LCPI7_4)
+; RV32-ILP32D-NEXT: lui a5, %hi(.LCPI7_5)
+; RV32-ILP32D-NEXT: addi a5, a5, %lo(.LCPI7_5)
+; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI7_6)
+; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI7_6)
+; RV32-ILP32D-NEXT: fld fa0, 0(a0)
+; RV32-ILP32D-NEXT: fld fa1, 0(a5)
+; RV32-ILP32D-NEXT: fld fa2, 0(a4)
+; RV32-ILP32D-NEXT: fld fa3, 0(a3)
+; RV32-ILP32D-NEXT: fld fa4, 0(a2)
+; RV32-ILP32D-NEXT: fld fa5, 0(a1)
+; RV32-ILP32D-NEXT: fld fa6, 0(a6)
+; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI7_7)
+; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI7_7)
+; RV32-ILP32D-NEXT: fld fa7, 0(a0)
+; RV32-ILP32D-NEXT: addi a0, zero, 1
+; RV32-ILP32D-NEXT: mv a1, zero
+; RV32-ILP32D-NEXT: addi a2, zero, 3
+; RV32-ILP32D-NEXT: mv a3, zero
+; RV32-ILP32D-NEXT: addi a4, zero, 5
+; RV32-ILP32D-NEXT: mv a5, zero
+; RV32-ILP32D-NEXT: addi a6, zero, 7
+; RV32-ILP32D-NEXT: mv a7, zero
+; RV32-ILP32D-NEXT: call callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs
+; RV32-ILP32D-NEXT: lw ra, 12(sp)
+; RV32-ILP32D-NEXT: addi sp, sp, 16
+; RV32-ILP32D-NEXT: ret
+ %1 = call i32 @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs(
+ i64 1, double 2.0, i64 3, double 4.0, i64 5, double 6.0, i32 7, double 8.0,
+ double 9.0, double 10.0, double 11.0, double 12.0, double 13.0)
+ ret i32 %1
+}
+
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_double_on_stack_exhausted_gprs_fprs(i64 %a, double %b, i64 %c, double %d, i64 %e, double %f, i64 %g, double %h, double %i, double %j, double %k, double %l, double %m) nounwind {
+; RV32-ILP32D-LABEL: callee_double_on_stack_exhausted_gprs_fprs:
+; RV32-ILP32D: # %bb.0:
+; RV32-ILP32D-NEXT: fld ft0, 0(sp)
+; RV32-ILP32D-NEXT: fcvt.w.d a0, ft0, rtz
+; RV32-ILP32D-NEXT: add a0, a6, a0
+; RV32-ILP32D-NEXT: ret
+ %g_trunc = trunc i64 %g to i32
+ %m_fptosi = fptosi double %m to i32
+ %1 = add i32 %g_trunc, %m_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_double_on_stack_exhausted_gprs_fprs() nounwind {
+; RV32-ILP32D-LABEL: caller_double_on_stack_exhausted_gprs_fprs:
+; RV32-ILP32D: # %bb.0:
+; RV32-ILP32D-NEXT: addi sp, sp, -16
+; RV32-ILP32D-NEXT: sw ra, 12(sp)
+; RV32-ILP32D-NEXT: lui a0, 262816
+; RV32-ILP32D-NEXT: sw a0, 4(sp)
+; RV32-ILP32D-NEXT: sw zero, 0(sp)
+; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI9_0)
+; RV32-ILP32D-NEXT: addi a6, a0, %lo(.LCPI9_0)
+; RV32-ILP32D-NEXT: lui a1, %hi(.LCPI9_1)
+; RV32-ILP32D-NEXT: addi a1, a1, %lo(.LCPI9_1)
+; RV32-ILP32D-NEXT: lui a2, %hi(.LCPI9_2)
+; RV32-ILP32D-NEXT: addi a2, a2, %lo(.LCPI9_2)
+; RV32-ILP32D-NEXT: lui a3, %hi(.LCPI9_3)
+; RV32-ILP32D-NEXT: addi a3, a3, %lo(.LCPI9_3)
+; RV32-ILP32D-NEXT: lui a4, %hi(.LCPI9_4)
+; RV32-ILP32D-NEXT: addi a4, a4, %lo(.LCPI9_4)
+; RV32-ILP32D-NEXT: lui a5, %hi(.LCPI9_5)
+; RV32-ILP32D-NEXT: addi a5, a5, %lo(.LCPI9_5)
+; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI9_6)
+; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI9_6)
+; RV32-ILP32D-NEXT: fld fa0, 0(a0)
+; RV32-ILP32D-NEXT: fld fa1, 0(a5)
+; RV32-ILP32D-NEXT: fld fa2, 0(a4)
+; RV32-ILP32D-NEXT: fld fa3, 0(a3)
+; RV32-ILP32D-NEXT: fld fa4, 0(a2)
+; RV32-ILP32D-NEXT: fld fa5, 0(a1)
+; RV32-ILP32D-NEXT: fld fa6, 0(a6)
+; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI9_7)
+; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI9_7)
+; RV32-ILP32D-NEXT: fld fa7, 0(a0)
+; RV32-ILP32D-NEXT: addi a0, zero, 1
+; RV32-ILP32D-NEXT: mv a1, zero
+; RV32-ILP32D-NEXT: addi a2, zero, 3
+; RV32-ILP32D-NEXT: mv a3, zero
+; RV32-ILP32D-NEXT: addi a4, zero, 5
+; RV32-ILP32D-NEXT: mv a5, zero
+; RV32-ILP32D-NEXT: addi a6, zero, 7
+; RV32-ILP32D-NEXT: mv a7, zero
+; RV32-ILP32D-NEXT: call callee_double_on_stack_exhausted_gprs_fprs
+; RV32-ILP32D-NEXT: lw ra, 12(sp)
+; RV32-ILP32D-NEXT: addi sp, sp, 16
+; RV32-ILP32D-NEXT: ret
+ %1 = call i32 @callee_double_on_stack_exhausted_gprs_fprs(
+ i64 1, double 2.0, i64 3, double 4.0, i64 5, double 6.0, i64 7, double 8.0,
+ double 9.0, double 10.0, double 11.0, double 12.0, double 13.0)
+ ret i32 %1
+}
+
+define double @callee_double_ret() nounwind {
+; RV32-ILP32D-LABEL: callee_double_ret:
+; RV32-ILP32D: # %bb.0:
+; RV32-ILP32D-NEXT: lui a0, %hi(.LCPI10_0)
+; RV32-ILP32D-NEXT: addi a0, a0, %lo(.LCPI10_0)
+; RV32-ILP32D-NEXT: fld fa0, 0(a0)
+; RV32-ILP32D-NEXT: ret
+ ret double 1.0
+}
+
+define i32 @caller_double_ret() nounwind {
+; RV32-ILP32D-LABEL: caller_double_ret:
+; RV32-ILP32D: # %bb.0:
+; RV32-ILP32D-NEXT: addi sp, sp, -16
+; RV32-ILP32D-NEXT: sw ra, 12(sp)
+; RV32-ILP32D-NEXT: call callee_double_ret
+; RV32-ILP32D-NEXT: fsd fa0, 0(sp)
+; RV32-ILP32D-NEXT: lw a0, 0(sp)
+; RV32-ILP32D-NEXT: lw ra, 12(sp)
+; RV32-ILP32D-NEXT: addi sp, sp, 16
+; RV32-ILP32D-NEXT: ret
+ %1 = call double @callee_double_ret()
+ %2 = bitcast double %1 to i64
+ %3 = trunc i64 %2 to i32
+ ret i32 %3
+}
diff --git a/llvm/test/CodeGen/RISCV/calling-conv-ilp32f-ilp32d-common.ll b/llvm/test/CodeGen/RISCV/calling-conv-ilp32f-ilp32d-common.ll
new file mode 100644
index 00000000000..5f3042dfe6e
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/calling-conv-ilp32f-ilp32d-common.ll
@@ -0,0 +1,221 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+f \
+; RUN: -target-abi ilp32f < %s \
+; RUN: | FileCheck -check-prefix=RV32-ILP32FD %s
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+d \
+; RUN: -target-abi ilp32d < %s \
+; RUN: | FileCheck -check-prefix=RV32-ILP32FD %s
+
+; This file contains tests that should have identical output for the ilp32f
+; and ilp32d ABIs.
+
+define i32 @callee_float_in_fpr(i32 %a, float %b) nounwind {
+; RV32-ILP32FD-LABEL: callee_float_in_fpr:
+; RV32-ILP32FD: # %bb.0:
+; RV32-ILP32FD-NEXT: fcvt.w.s a1, fa0, rtz
+; RV32-ILP32FD-NEXT: add a0, a0, a1
+; RV32-ILP32FD-NEXT: ret
+ %b_fptosi = fptosi float %b to i32
+ %1 = add i32 %a, %b_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_float_in_fpr() nounwind {
+; RV32-ILP32FD-LABEL: caller_float_in_fpr:
+; RV32-ILP32FD: # %bb.0:
+; RV32-ILP32FD-NEXT: addi sp, sp, -16
+; RV32-ILP32FD-NEXT: sw ra, 12(sp)
+; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI1_0)
+; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI1_0)
+; RV32-ILP32FD-NEXT: flw fa0, 0(a0)
+; RV32-ILP32FD-NEXT: addi a0, zero, 1
+; RV32-ILP32FD-NEXT: call callee_float_in_fpr
+; RV32-ILP32FD-NEXT: lw ra, 12(sp)
+; RV32-ILP32FD-NEXT: addi sp, sp, 16
+; RV32-ILP32FD-NEXT: ret
+ %1 = call i32 @callee_float_in_fpr(i32 1, float 2.0)
+ ret i32 %1
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_float_in_fpr_exhausted_gprs(i64 %a, i64 %b, i64 %c, i64 %d, i32 %e, float %f) nounwind {
+; RV32-ILP32FD-LABEL: callee_float_in_fpr_exhausted_gprs:
+; RV32-ILP32FD: # %bb.0:
+; RV32-ILP32FD-NEXT: fcvt.w.s a0, fa0, rtz
+; RV32-ILP32FD-NEXT: lw a1, 0(sp)
+; RV32-ILP32FD-NEXT: add a0, a1, a0
+; RV32-ILP32FD-NEXT: ret
+ %f_fptosi = fptosi float %f to i32
+ %1 = add i32 %e, %f_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_float_in_fpr_exhausted_gprs() nounwind {
+; RV32-ILP32FD-LABEL: caller_float_in_fpr_exhausted_gprs:
+; RV32-ILP32FD: # %bb.0:
+; RV32-ILP32FD-NEXT: addi sp, sp, -16
+; RV32-ILP32FD-NEXT: sw ra, 12(sp)
+; RV32-ILP32FD-NEXT: addi a0, zero, 5
+; RV32-ILP32FD-NEXT: sw a0, 0(sp)
+; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI3_0)
+; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI3_0)
+; RV32-ILP32FD-NEXT: flw fa0, 0(a0)
+; RV32-ILP32FD-NEXT: addi a0, zero, 1
+; RV32-ILP32FD-NEXT: mv a1, zero
+; RV32-ILP32FD-NEXT: addi a2, zero, 2
+; RV32-ILP32FD-NEXT: mv a3, zero
+; RV32-ILP32FD-NEXT: addi a4, zero, 3
+; RV32-ILP32FD-NEXT: mv a5, zero
+; RV32-ILP32FD-NEXT: addi a6, zero, 4
+; RV32-ILP32FD-NEXT: mv a7, zero
+; RV32-ILP32FD-NEXT: call callee_float_in_fpr_exhausted_gprs
+; RV32-ILP32FD-NEXT: lw ra, 12(sp)
+; RV32-ILP32FD-NEXT: addi sp, sp, 16
+; RV32-ILP32FD-NEXT: ret
+ %1 = call i32 @callee_float_in_fpr_exhausted_gprs(
+ i64 1, i64 2, i64 3, i64 4, i32 5, float 6.0)
+ ret i32 %1
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_float_in_gpr_exhausted_fprs(float %a, float %b, float %c, float %d, float %e, float %f, float %g, float %h, float %i) nounwind {
+; RV32-ILP32FD-LABEL: callee_float_in_gpr_exhausted_fprs:
+; RV32-ILP32FD: # %bb.0:
+; RV32-ILP32FD-NEXT: fcvt.w.s a1, fa7, rtz
+; RV32-ILP32FD-NEXT: fmv.w.x ft0, a0
+; RV32-ILP32FD-NEXT: fcvt.w.s a0, ft0, rtz
+; RV32-ILP32FD-NEXT: add a0, a1, a0
+; RV32-ILP32FD-NEXT: ret
+ %h_fptosi = fptosi float %h to i32
+ %i_fptosi = fptosi float %i to i32
+ %1 = add i32 %h_fptosi, %i_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_float_in_gpr_exhausted_fprs() nounwind {
+; RV32-ILP32FD-LABEL: caller_float_in_gpr_exhausted_fprs:
+; RV32-ILP32FD: # %bb.0:
+; RV32-ILP32FD-NEXT: addi sp, sp, -16
+; RV32-ILP32FD-NEXT: sw ra, 12(sp)
+; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI5_0)
+; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI5_0)
+; RV32-ILP32FD-NEXT: lui a1, %hi(.LCPI5_1)
+; RV32-ILP32FD-NEXT: addi a1, a1, %lo(.LCPI5_1)
+; RV32-ILP32FD-NEXT: lui a2, %hi(.LCPI5_2)
+; RV32-ILP32FD-NEXT: addi a2, a2, %lo(.LCPI5_2)
+; RV32-ILP32FD-NEXT: lui a3, %hi(.LCPI5_3)
+; RV32-ILP32FD-NEXT: addi a3, a3, %lo(.LCPI5_3)
+; RV32-ILP32FD-NEXT: lui a4, %hi(.LCPI5_4)
+; RV32-ILP32FD-NEXT: addi a4, a4, %lo(.LCPI5_4)
+; RV32-ILP32FD-NEXT: lui a5, %hi(.LCPI5_5)
+; RV32-ILP32FD-NEXT: addi a5, a5, %lo(.LCPI5_5)
+; RV32-ILP32FD-NEXT: flw fa0, 0(a5)
+; RV32-ILP32FD-NEXT: flw fa1, 0(a4)
+; RV32-ILP32FD-NEXT: flw fa2, 0(a3)
+; RV32-ILP32FD-NEXT: flw fa3, 0(a2)
+; RV32-ILP32FD-NEXT: flw fa4, 0(a1)
+; RV32-ILP32FD-NEXT: flw fa5, 0(a0)
+; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI5_6)
+; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI5_6)
+; RV32-ILP32FD-NEXT: flw fa6, 0(a0)
+; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI5_7)
+; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI5_7)
+; RV32-ILP32FD-NEXT: flw fa7, 0(a0)
+; RV32-ILP32FD-NEXT: lui a0, 266496
+; RV32-ILP32FD-NEXT: call callee_float_in_gpr_exhausted_fprs
+; RV32-ILP32FD-NEXT: lw ra, 12(sp)
+; RV32-ILP32FD-NEXT: addi sp, sp, 16
+; RV32-ILP32FD-NEXT: ret
+ %1 = call i32 @callee_float_in_gpr_exhausted_fprs(
+ float 1.0, float 2.0, float 3.0, float 4.0, float 5.0, float 6.0,
+ float 7.0, float 8.0, float 9.0)
+ ret i32 %1
+}
+
+; Must keep define on a single line due to an update_llc_test_checks.py limitation
+define i32 @callee_float_on_stack_exhausted_gprs_fprs(i64 %a, float %b, i64 %c, float %d, i64 %e, float %f, i64 %g, float %h, float %i, float %j, float %k, float %l, float %m) nounwind {
+; RV32-ILP32FD-LABEL: callee_float_on_stack_exhausted_gprs_fprs:
+; RV32-ILP32FD: # %bb.0:
+; RV32-ILP32FD-NEXT: flw ft0, 0(sp)
+; RV32-ILP32FD-NEXT: fcvt.w.s a0, ft0, rtz
+; RV32-ILP32FD-NEXT: add a0, a6, a0
+; RV32-ILP32FD-NEXT: ret
+ %g_trunc = trunc i64 %g to i32
+ %m_fptosi = fptosi float %m to i32
+ %1 = add i32 %g_trunc, %m_fptosi
+ ret i32 %1
+}
+
+define i32 @caller_float_on_stack_exhausted_gprs_fprs() nounwind {
+; RV32-ILP32FD-LABEL: caller_float_on_stack_exhausted_gprs_fprs:
+; RV32-ILP32FD: # %bb.0:
+; RV32-ILP32FD-NEXT: addi sp, sp, -16
+; RV32-ILP32FD-NEXT: sw ra, 12(sp)
+; RV32-ILP32FD-NEXT: lui a0, 267520
+; RV32-ILP32FD-NEXT: sw a0, 0(sp)
+; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI7_0)
+; RV32-ILP32FD-NEXT: addi a6, a0, %lo(.LCPI7_0)
+; RV32-ILP32FD-NEXT: lui a1, %hi(.LCPI7_1)
+; RV32-ILP32FD-NEXT: addi a1, a1, %lo(.LCPI7_1)
+; RV32-ILP32FD-NEXT: lui a2, %hi(.LCPI7_2)
+; RV32-ILP32FD-NEXT: addi a2, a2, %lo(.LCPI7_2)
+; RV32-ILP32FD-NEXT: lui a3, %hi(.LCPI7_3)
+; RV32-ILP32FD-NEXT: addi a3, a3, %lo(.LCPI7_3)
+; RV32-ILP32FD-NEXT: lui a4, %hi(.LCPI7_4)
+; RV32-ILP32FD-NEXT: addi a4, a4, %lo(.LCPI7_4)
+; RV32-ILP32FD-NEXT: lui a5, %hi(.LCPI7_5)
+; RV32-ILP32FD-NEXT: addi a5, a5, %lo(.LCPI7_5)
+; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI7_6)
+; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI7_6)
+; RV32-ILP32FD-NEXT: flw fa0, 0(a0)
+; RV32-ILP32FD-NEXT: flw fa1, 0(a5)
+; RV32-ILP32FD-NEXT: flw fa2, 0(a4)
+; RV32-ILP32FD-NEXT: flw fa3, 0(a3)
+; RV32-ILP32FD-NEXT: flw fa4, 0(a2)
+; RV32-ILP32FD-NEXT: flw fa5, 0(a1)
+; RV32-ILP32FD-NEXT: flw fa6, 0(a6)
+; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI7_7)
+; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI7_7)
+; RV32-ILP32FD-NEXT: flw fa7, 0(a0)
+; RV32-ILP32FD-NEXT: addi a0, zero, 1
+; RV32-ILP32FD-NEXT: mv a1, zero
+; RV32-ILP32FD-NEXT: addi a2, zero, 3
+; RV32-ILP32FD-NEXT: mv a3, zero
+; RV32-ILP32FD-NEXT: addi a4, zero, 5
+; RV32-ILP32FD-NEXT: mv a5, zero
+; RV32-ILP32FD-NEXT: addi a6, zero, 7
+; RV32-ILP32FD-NEXT: mv a7, zero
+; RV32-ILP32FD-NEXT: call callee_float_on_stack_exhausted_gprs_fprs
+; RV32-ILP32FD-NEXT: lw ra, 12(sp)
+; RV32-ILP32FD-NEXT: addi sp, sp, 16
+; RV32-ILP32FD-NEXT: ret
+ %1 = call i32 @callee_float_on_stack_exhausted_gprs_fprs(
+ i64 1, float 2.0, i64 3, float 4.0, i64 5, float 6.0, i64 7, float 8.0,
+ float 9.0, float 10.0, float 11.0, float 12.0, float 13.0)
+ ret i32 %1
+}
+
+define float @callee_float_ret() nounwind {
+; RV32-ILP32FD-LABEL: callee_float_ret:
+; RV32-ILP32FD: # %bb.0:
+; RV32-ILP32FD-NEXT: lui a0, %hi(.LCPI8_0)
+; RV32-ILP32FD-NEXT: addi a0, a0, %lo(.LCPI8_0)
+; RV32-ILP32FD-NEXT: flw fa0, 0(a0)
+; RV32-ILP32FD-NEXT: ret
+ ret float 1.0
+}
+
+define i32 @caller_float_ret() nounwind {
+; RV32-ILP32FD-LABEL: caller_float_ret:
+; RV32-ILP32FD: # %bb.0:
+; RV32-ILP32FD-NEXT: addi sp, sp, -16
+; RV32-ILP32FD-NEXT: sw ra, 12(sp)
+; RV32-ILP32FD-NEXT: call callee_float_ret
+; RV32-ILP32FD-NEXT: fmv.x.w a0, fa0
+; RV32-ILP32FD-NEXT: lw ra, 12(sp)
+; RV32-ILP32FD-NEXT: addi sp, sp, 16
+; RV32-ILP32FD-NEXT: ret
+ %1 = call float @callee_float_ret()
+ %2 = bitcast float %1 to i32
+ ret i32 %2
+}
diff --git a/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-common.ll b/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-common.ll
index 205f57ff437..1f5730c9ab8 100644
--- a/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-common.ll
+++ b/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-common.ll
@@ -1,6 +1,9 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV64I %s
+; RUN: llc -mtriple=riscv64 -mattr=+f -target-abi lp64f \
+; RUN: -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I %s
; This file contains tests that should have identical output for the lp64 and
; lp64f ABIs. It doesn't check codegen when frame pointer elimination is
diff --git a/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll b/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll
index d1232824f40..fb27c3ae3e9 100644
--- a/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll
+++ b/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll
@@ -1,6 +1,12 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV64I %s
+; RUN: llc -mtriple=riscv64 -mattr=+f -target-abi lp64f \
+; RUN: -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I %s
+; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64d \
+; RUN: -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I %s
; This file contains tests that should have identical output for the lp64,
; lp64f, and lp64d ABIs. i.e. where no arguments are passed according to
diff --git a/llvm/test/CodeGen/RISCV/target-abi-valid.ll b/llvm/test/CodeGen/RISCV/target-abi-valid.ll
index 2223345249d..2bd7dde3cd8 100644
--- a/llvm/test/CodeGen/RISCV/target-abi-valid.ll
+++ b/llvm/test/CodeGen/RISCV/target-abi-valid.ll
@@ -14,6 +14,18 @@
; RUN: | FileCheck -check-prefix=CHECK-IMP %s
; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64 < %s \
; RUN: | FileCheck -check-prefix=CHECK-IMP %s
+; RUN: llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f < %s 2>&1 \
+; RUN: | FileCheck -check-prefix=CHECK-IMP %s
+; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32f < %s 2>&1 \
+; RUN: | FileCheck -check-prefix=CHECK-IMP %s
+; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d < %s 2>&1 \
+; RUN: | FileCheck -check-prefix=CHECK-IMP %s
+; RUN: llc -mtriple=riscv64 -mattr=+f -target-abi lp64f < %s 2>&1 \
+; RUN: | FileCheck -check-prefix=CHECK-IMP %s
+; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64f < %s 2>&1 \
+; RUN: | FileCheck -check-prefix=CHECK-IMP %s
+; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64d < %s 2>&1 \
+; RUN: | FileCheck -check-prefix=CHECK-IMP %s
define void @nothing() nounwind {
; CHECK-IMP-LABEL: nothing:
@@ -22,19 +34,7 @@ define void @nothing() nounwind {
ret void
}
-; RUN: not llc -mtriple=riscv32 -mattr=+f -target-abi ilp32f < %s 2>&1 \
-; RUN: | FileCheck -check-prefix=CHECK-UNIMP %s
-; RUN: not llc -mtriple=riscv32 -mattr=+d -target-abi ilp32f < %s 2>&1 \
-; RUN: | FileCheck -check-prefix=CHECK-UNIMP %s
-; RUN: not llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d < %s 2>&1 \
-; RUN: | FileCheck -check-prefix=CHECK-UNIMP %s
; RUN: not llc -mtriple=riscv32 -target-abi ilp32e < %s 2>&1 \
; RUN: | FileCheck -check-prefix=CHECK-UNIMP %s
-; RUN: not llc -mtriple=riscv64 -mattr=+f -target-abi lp64f < %s 2>&1 \
-; RUN: | FileCheck -check-prefix=CHECK-UNIMP %s
-; RUN: not llc -mtriple=riscv64 -mattr=+d -target-abi lp64f < %s 2>&1 \
-; RUN: | FileCheck -check-prefix=CHECK-UNIMP %s
-; RUN: not llc -mtriple=riscv64 -mattr=+d -target-abi lp64d < %s 2>&1 \
-; RUN: | FileCheck -check-prefix=CHECK-UNIMP %s
; CHECK-UNIMP: LLVM ERROR: Don't know how to lower this ABI
diff --git a/llvm/test/CodeGen/RISCV/vararg.ll b/llvm/test/CodeGen/RISCV/vararg.ll
index 5486314af1d..34132825c2a 100644
--- a/llvm/test/CodeGen/RISCV/vararg.ll
+++ b/llvm/test/CodeGen/RISCV/vararg.ll
@@ -5,16 +5,26 @@
; RUN: | FileCheck -check-prefix=ILP32-ILP32F-WITHFP %s
; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV32D-ILP32-ILP32F-ILP32D-FPELIM %s
+; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32f \
+; RUN: -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV32D-ILP32-ILP32F-ILP32D-FPELIM %s
+; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d \
+; RUN: -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV32D-ILP32-ILP32F-ILP32D-FPELIM %s
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=LP64-LP64F-LP64D-FPELIM %s
+; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64f \
+; RUN: -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=LP64-LP64F-LP64D-FPELIM %s
+; RUN: llc -mtriple=riscv64 -mattr=+d -target-abi lp64d \
+; RUN: -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=LP64-LP64F-LP64D-FPELIM %s
; RUN: llc -mtriple=riscv64 -verify-machineinstrs -frame-pointer=all < %s \
; RUN: | FileCheck -check-prefix=LP64-LP64F-LP64D-WITHFP %s
-; TODO: RUN lines for ilp32f/ilp32d/lp64f/lp64d must be added when hard float
-; ABI Support lands. The same vararg calling convention is used for
-; ilp32/ilp32f/ilp32d and for lp64/lp64f/lp64d. Different CHECK lines are
-; required for RV32D due to slight codegen differences due to the way the
-; f64 load operations are lowered.
+; The same vararg calling convention is used for ilp32/ilp32f/ilp32d and for
+; lp64/lp64f/lp64d. Different CHECK lines are required for RV32D due to slight
+; codegen differences due to the way the f64 load operations are lowered.
declare void @llvm.va_start(i8*)
declare void @llvm.va_end(i8*)
OpenPOWER on IntegriCloud