-
Notifications
You must be signed in to change notification settings - Fork 15k
[RISCV] Support PreserveMost calling convention #148214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-backend-risc-v Author: Pengcheng Wang (wangpc-pp) ChangesThis adds the simplest implementation of Fixes #148147. Full diff: https://github.com/llvm/llvm-project/pull/148214.diff 4 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.td b/llvm/lib/Target/RISCV/RISCVCallingConv.td
index cbf039edec273..90e5019019bed 100644
--- a/llvm/lib/Target/RISCV/RISCVCallingConv.td
+++ b/llvm/lib/Target/RISCV/RISCVCallingConv.td
@@ -93,3 +93,5 @@ def CSR_XLEN_F32_V_Interrupt_RVE: CalleeSavedRegs<(sub CSR_XLEN_F32_V_Interrupt,
// Same as CSR_XLEN_F64_V_Interrupt, but excluding X16-X31.
def CSR_XLEN_F64_V_Interrupt_RVE: CalleeSavedRegs<(sub CSR_XLEN_F64_V_Interrupt,
(sequence "X%u", 16, 31))>;
+
+def CSR_RT_MostRegs : CalleeSavedRegs<(add (sequence "X%u", 5, 31))>;
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 456f3aedbf034..6feb53202b7f2 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -22205,6 +22205,7 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
case CallingConv::C:
case CallingConv::Fast:
case CallingConv::SPIR_KERNEL:
+ case CallingConv::PreserveMost:
case CallingConv::GRAAL:
case CallingConv::RISCV_VectorCall:
#define CC_VLS_CASE(ABI_VLEN) case CallingConv::RISCV_VLSCall_##ABI_VLEN:
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
index 540412366026b..44c7ca3587cc1 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
@@ -68,6 +68,8 @@ RISCVRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
auto &Subtarget = MF->getSubtarget<RISCVSubtarget>();
if (MF->getFunction().getCallingConv() == CallingConv::GHC)
return CSR_NoRegs_SaveList;
+ if (MF->getFunction().getCallingConv() == CallingConv::PreserveMost)
+ return CSR_RT_MostRegs_SaveList;
if (MF->getFunction().hasFnAttribute("interrupt")) {
if (Subtarget.hasVInstructions()) {
if (Subtarget.hasStdExtD())
diff --git a/llvm/test/CodeGen/RISCV/calling-conv-preserve-most.ll b/llvm/test/CodeGen/RISCV/calling-conv-preserve-most.ll
new file mode 100644
index 0000000000000..a0345363601a5
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/calling-conv-preserve-most.ll
@@ -0,0 +1,165 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 < %s | FileCheck %s -check-prefix=RV32
+; RUN: llc -mtriple=riscv64 < %s | FileCheck %s -check-prefix=RV64
+
+; Check the PreserveMost calling convention works.
+
+declare void @standard_cc_func()
+declare preserve_mostcc void @preserve_mostcc_func()
+
+define preserve_mostcc void @preserve_mostcc1() nounwind {
+; RV32-LABEL: preserve_mostcc1:
+; RV32: # %bb.0: # %entry
+; RV32-NEXT: addi sp, sp, -64
+; RV32-NEXT: sw t0, 60(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw t1, 56(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw t2, 52(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a0, 48(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a1, 44(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a2, 40(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a3, 36(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a4, 32(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a5, 28(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a6, 24(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a7, 20(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw t3, 16(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw t4, 12(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw t5, 8(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw t6, 4(sp) # 4-byte Folded Spill
+; RV32-NEXT: call standard_cc_func
+; RV32-NEXT: lw t0, 60(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw t1, 56(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw t2, 52(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a0, 48(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a1, 44(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a2, 40(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a3, 36(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a4, 32(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a5, 28(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a6, 24(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a7, 20(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw t3, 16(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw t4, 12(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw t5, 8(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw t6, 4(sp) # 4-byte Folded Reload
+; RV32-NEXT: addi sp, sp, 64
+; RV32-NEXT: ret
+;
+; RV64-LABEL: preserve_mostcc1:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: addi sp, sp, -128
+; RV64-NEXT: sd t0, 120(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd t1, 112(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd t2, 104(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a0, 96(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a1, 88(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a2, 80(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a3, 72(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a4, 64(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a5, 56(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a6, 48(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a7, 40(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd t3, 32(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd t4, 24(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd t5, 16(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd t6, 8(sp) # 8-byte Folded Spill
+; RV64-NEXT: call standard_cc_func
+; RV64-NEXT: ld t0, 120(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld t1, 112(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld t2, 104(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a0, 96(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a1, 88(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a2, 80(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a3, 72(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a4, 64(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a5, 56(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a6, 48(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a7, 40(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld t3, 32(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld t4, 24(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld t5, 16(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld t6, 8(sp) # 8-byte Folded Reload
+; RV64-NEXT: addi sp, sp, 128
+; RV64-NEXT: ret
+entry:
+ call void @standard_cc_func()
+ ret void
+}
+
+define preserve_mostcc void @preserve_mostcc2() nounwind {
+; RV32-LABEL: preserve_mostcc2:
+; RV32: # %bb.0:
+; RV32-NEXT: addi sp, sp, -64
+; RV32-NEXT: sw t0, 60(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw t1, 56(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw t2, 52(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a0, 48(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a1, 44(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a2, 40(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a3, 36(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a4, 32(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a5, 28(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a6, 24(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw a7, 20(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw t3, 16(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw t4, 12(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw t5, 8(sp) # 4-byte Folded Spill
+; RV32-NEXT: sw t6, 4(sp) # 4-byte Folded Spill
+; RV32-NEXT: call preserve_mostcc_func
+; RV32-NEXT: lw t0, 60(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw t1, 56(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw t2, 52(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a0, 48(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a1, 44(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a2, 40(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a3, 36(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a4, 32(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a5, 28(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a6, 24(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw a7, 20(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw t3, 16(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw t4, 12(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw t5, 8(sp) # 4-byte Folded Reload
+; RV32-NEXT: lw t6, 4(sp) # 4-byte Folded Reload
+; RV32-NEXT: addi sp, sp, 64
+; RV32-NEXT: ret
+;
+; RV64-LABEL: preserve_mostcc2:
+; RV64: # %bb.0:
+; RV64-NEXT: addi sp, sp, -128
+; RV64-NEXT: sd t0, 120(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd t1, 112(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd t2, 104(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a0, 96(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a1, 88(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a2, 80(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a3, 72(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a4, 64(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a5, 56(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a6, 48(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd a7, 40(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd t3, 32(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd t4, 24(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd t5, 16(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd t6, 8(sp) # 8-byte Folded Spill
+; RV64-NEXT: call preserve_mostcc_func
+; RV64-NEXT: ld t0, 120(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld t1, 112(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld t2, 104(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a0, 96(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a1, 88(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a2, 80(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a3, 72(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a4, 64(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a5, 56(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a6, 48(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld a7, 40(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld t3, 32(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld t4, 24(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld t5, 16(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld t6, 8(sp) # 8-byte Folded Reload
+; RV64-NEXT: addi sp, sp, 128
+; RV64-NEXT: ret
+ call preserve_mostcc void @preserve_mostcc_func()
+ ret void
+}
|
It is appreciated if you can test its functionality @CaiWeiran @folkertdev. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably update the LangRef to document that RISC-V supports it?
1fff14f
to
e3a2e57
Compare
c8e4770
to
3c4864d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks
This adds the simplest implementation of `PreserveMost` calling convention and we preserve `x5-x31` registers. Fixes llvm#148147.
3edb095
to
2900358
Compare
d734932
to
237d6cc
Compare
This adds the simplest implementation of `PreserveMost` calling convention and we preserve `x5-x31` (except x6/x7/x28) registers. Fixes llvm#148147.
This adds the simplest implementation of
PreserveMost
callingconvention and we preserve
x5-x31
(except x6/x7/x28) registers.Fixes #148147.