[llvm] [AArch64][SME] Add calling convention for __arm_get_current_vg (PR #93963)
via llvm-commits
llvm-commits at lists.llvm.org
Fri May 31 06:58:54 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir
@llvm/pr-subscribers-backend-aarch64
Author: Kerry McLaughlin (kmclaughlin-arm)
<details>
<summary>Changes</summary>
Adds a calling convention for calls to the `__arm_get_current_vg` support
routine, which preserves X1-X15, X19-X29, SP, Z0-Z31 & P0-P15.
See https://github.com/ARM-software/abi-aa/pull/263
---
Full diff: https://github.com/llvm/llvm-project/pull/93963.diff
8 Files Affected:
- (modified) llvm/include/llvm/AsmParser/LLToken.h (+1)
- (modified) llvm/include/llvm/IR/CallingConv.h (+3)
- (modified) llvm/lib/AsmParser/LLLexer.cpp (+1)
- (modified) llvm/lib/AsmParser/LLParser.cpp (+4)
- (modified) llvm/lib/IR/AsmWriter.cpp (+3)
- (modified) llvm/lib/Target/AArch64/AArch64CallingConvention.td (+8)
- (modified) llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp (+19)
- (modified) llvm/test/CodeGen/AArch64/sme-support-routines-calling-convention.ll (+15)
``````````diff
diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h
index 0cbcdcd9ffac7..86d4dae4dc732 100644
--- a/llvm/include/llvm/AsmParser/LLToken.h
+++ b/llvm/include/llvm/AsmParser/LLToken.h
@@ -146,6 +146,7 @@ enum Kind {
kw_aarch64_vector_pcs,
kw_aarch64_sve_vector_pcs,
kw_aarch64_sme_preservemost_from_x0,
+ kw_aarch64_sme_preservemost_from_x1,
kw_aarch64_sme_preservemost_from_x2,
kw_msp430_intrcc,
kw_avr_intrcc,
diff --git a/llvm/include/llvm/IR/CallingConv.h b/llvm/include/llvm/IR/CallingConv.h
index a05d1a4d58784..55e32028e3ed0 100644
--- a/llvm/include/llvm/IR/CallingConv.h
+++ b/llvm/include/llvm/IR/CallingConv.h
@@ -267,6 +267,9 @@ namespace CallingConv {
/// Calling convention used for RISC-V V-extension.
RISCV_VectorCall = 110,
+ /// Preserve X1-X15, X19-X29, SP, Z0-Z31, P0-P15.
+ AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1 = 111,
+
/// The highest possible ID. Must be some 2^k - 1.
MaxID = 1023
};
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 8ded07ffd8bd2..9c340cfe0c243 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -603,6 +603,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(aarch64_vector_pcs);
KEYWORD(aarch64_sve_vector_pcs);
KEYWORD(aarch64_sme_preservemost_from_x0);
+ KEYWORD(aarch64_sme_preservemost_from_x1);
KEYWORD(aarch64_sme_preservemost_from_x2);
KEYWORD(msp430_intrcc);
KEYWORD(avr_intrcc);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 2902bd9fe17c4..53a23bafae59a 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -2153,6 +2153,7 @@ void LLParser::parseOptionalDLLStorageClass(unsigned &Res) {
/// ::= 'aarch64_vector_pcs'
/// ::= 'aarch64_sve_vector_pcs'
/// ::= 'aarch64_sme_preservemost_from_x0'
+/// ::= 'aarch64_sme_preservemost_from_x1'
/// ::= 'aarch64_sme_preservemost_from_x2'
/// ::= 'msp430_intrcc'
/// ::= 'avr_intrcc'
@@ -2212,6 +2213,9 @@ bool LLParser::parseOptionalCallingConv(unsigned &CC) {
case lltok::kw_aarch64_sme_preservemost_from_x0:
CC = CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0;
break;
+ case lltok::kw_aarch64_sme_preservemost_from_x1:
+ CC = CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1;
+ break;
case lltok::kw_aarch64_sme_preservemost_from_x2:
CC = CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2;
break;
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 941f6a7a7d823..88545d303a2a0 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -326,6 +326,9 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) {
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0:
Out << "aarch64_sme_preservemost_from_x0";
break;
+ case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1:
+ Out << "aarch64_sme_preservemost_from_x1";
+ break;
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2:
Out << "aarch64_sme_preservemost_from_x2";
break;
diff --git a/llvm/lib/Target/AArch64/AArch64CallingConvention.td b/llvm/lib/Target/AArch64/AArch64CallingConvention.td
index 8e67f0f5c8815..15398003b3c6d 100644
--- a/llvm/lib/Target/AArch64/AArch64CallingConvention.td
+++ b/llvm/lib/Target/AArch64/AArch64CallingConvention.td
@@ -563,6 +563,14 @@ def CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0
(sequence "X%u",19, 28),
LR, FP)>;
+// SME ABI support routines such as __arm_get_current_vg preserve most registers.
+def CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1
+ : CalleeSavedRegs<(add (sequence "Z%u", 0, 31),
+ (sequence "P%u", 0, 15),
+ (sequence "X%u", 1, 15),
+ (sequence "X%u",19, 28),
+ LR, FP)>;
+
// SME ABI support routines __arm_sme_state preserves most registers.
def CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2
: CalleeSavedRegs<(add (sequence "Z%u", 0, 31),
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
index ad29003f1e817..8c214a6287d15 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -108,6 +108,12 @@ AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
"Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is "
"only supported to improve calls to SME ACLE save/restore/disable-za "
"functions, and is not intended to be used beyond that scope.");
+ if (MF->getFunction().getCallingConv() ==
+ CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1)
+ report_fatal_error(
+ "Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1 is "
+ "only supported to improve calls to SME ACLE __arm_get_current_vg function, "
+ "and is not intended to be used beyond that scope.");
if (MF->getFunction().getCallingConv() ==
CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2)
report_fatal_error(
@@ -154,6 +160,12 @@ AArch64RegisterInfo::getDarwinCalleeSavedRegs(const MachineFunction *MF) const {
"Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is "
"only supported to improve calls to SME ACLE save/restore/disable-za "
"functions, and is not intended to be used beyond that scope.");
+ if (MF->getFunction().getCallingConv() ==
+ CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1)
+ report_fatal_error(
+ "Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1 is "
+ "only supported to improve calls to SME ACLE __arm_get_current_vg function, "
+ "and is not intended to be used beyond that scope.");
if (MF->getFunction().getCallingConv() ==
CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2)
report_fatal_error(
@@ -236,6 +248,10 @@ AArch64RegisterInfo::getDarwinCallPreservedMask(const MachineFunction &MF,
report_fatal_error(
"Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is "
"unsupported on Darwin.");
+ if (CC == CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1)
+ report_fatal_error(
+ "Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1 is "
+ "unsupported on Darwin.");
if (CC == CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2)
report_fatal_error(
"Calling convention AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2 is "
@@ -281,6 +297,8 @@ AArch64RegisterInfo::getCallPreservedMask(const MachineFunction &MF,
: CSR_AArch64_SVE_AAPCS_RegMask;
if (CC == CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0)
return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0_RegMask;
+ if (CC == CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1)
+ return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1_RegMask;
if (CC == CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2)
return CSR_AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2_RegMask;
if (CC == CallingConv::CFGuard_Check)
@@ -640,6 +658,7 @@ bool AArch64RegisterInfo::isArgumentRegister(const MachineFunction &MF,
case CallingConv::AArch64_VectorCall:
case CallingConv::AArch64_SVE_VectorCall:
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0:
+ case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1:
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2:
if (STI.isTargetWindows())
return HasReg(CC_AArch64_Win64PCS_ArgRegs, Reg);
diff --git a/llvm/test/CodeGen/AArch64/sme-support-routines-calling-convention.ll b/llvm/test/CodeGen/AArch64/sme-support-routines-calling-convention.ll
index d88deec40ce72..8fcd8eb24ee06 100644
--- a/llvm/test/CodeGen/AArch64/sme-support-routines-calling-convention.ll
+++ b/llvm/test/CodeGen/AArch64/sme-support-routines-calling-convention.ll
@@ -18,6 +18,20 @@ define void @test_sme_calling_convention_x0() nounwind {
ret void
}
+define i64 @test_sme_calling_convention_x1() nounwind {
+; CHECK-LABEL: test_sme_calling_convention_x1:
+; CHECK: // %bb.0:
+; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-NEXT: bl __arm_get_current_vg
+; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
+; CHECK-NEXT: ret
+;
+; CHECK-CSRMASK-LABEL: name: test_sme_calling_convention_x1
+; CHECK-CSRMASK: BL @__arm_get_current_vg, csr_aarch64_sme_abi_support_routines_preservemost_from_x1
+ %vg = call aarch64_sme_preservemost_from_x1 i64 @__arm_get_current_vg()
+ ret i64 %vg
+}
+
define i64 @test_sme_calling_convention_x2() nounwind {
; CHECK-LABEL: test_sme_calling_convention_x2:
; CHECK: // %bb.0:
@@ -34,4 +48,5 @@ define i64 @test_sme_calling_convention_x2() nounwind {
}
declare void @__arm_tpidr2_save()
+declare i64 @__arm_get_current_vg()
declare {i64, i64} @__arm_sme_state()
``````````
</details>
https://github.com/llvm/llvm-project/pull/93963
More information about the llvm-commits
mailing list