58 changes: 55 additions & 3 deletions llvm/test/CodeGen/RISCV/callee-saved-fpr64s.ll
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
12 changes: 12 additions & 0 deletions llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
Original file line number Diff line number Diff line change
@@ -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

Expand Down
6 changes: 6 additions & 0 deletions llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-common.ll
Original file line number Diff line number Diff line change
@@ -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
Expand Down
12 changes: 12 additions & 0 deletions llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll
Original file line number Diff line number Diff line change
@@ -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
Expand Down
294 changes: 294 additions & 0 deletions llvm/test/CodeGen/RISCV/calling-conv-ilp32d.ll
Original file line number Diff line number Diff line change
@@ -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
}
221 changes: 221 additions & 0 deletions llvm/test/CodeGen/RISCV/calling-conv-ilp32f-ilp32d-common.ll
Original file line number Diff line number Diff line change
@@ -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
}
3 changes: 3 additions & 0 deletions llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-common.ll
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
24 changes: 12 additions & 12 deletions llvm/test/CodeGen/RISCV/target-abi-valid.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
20 changes: 15 additions & 5 deletions llvm/test/CodeGen/RISCV/vararg.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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*)
Expand Down