[clang] 75bb815 - [AArch64][SVE] Add aarch64_sve_pcs attribute to Clang
Matt Devereau via cfe-commits
cfe-commits at lists.llvm.org
Wed May 11 06:36:35 PDT 2022
Author: Matt Devereau
Date: 2022-05-11T13:33:56Z
New Revision: 75bb815231f6967bd5f4e24143141b9fe69d01f8
URL: https://github.com/llvm/llvm-project/commit/75bb815231f6967bd5f4e24143141b9fe69d01f8
DIFF: https://github.com/llvm/llvm-project/commit/75bb815231f6967bd5f4e24143141b9fe69d01f8.diff
LOG: [AArch64][SVE] Add aarch64_sve_pcs attribute to Clang
Enable function attribute aarch64_sve_pcs at the C level, which correspondes to
aarch64_sve_vector_pcs at the LLVM IR level.
This requirement was created by this addition to the ARM C Language Extension:
https://github.com/ARM-software/acle/pull/194
Differential Revision: https://reviews.llvm.org/D124998
Added:
clang/test/CodeGen/aarch64-svepcs.c
clang/test/Sema/aarch64-svepcs.c
Modified:
clang/include/clang-c/Index.h
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Basic/Specifiers.h
clang/lib/AST/ItaniumMangle.cpp
clang/lib/AST/Type.cpp
clang/lib/AST/TypePrinter.cpp
clang/lib/Basic/Targets/AArch64.cpp
clang/lib/CodeGen/CGCall.cpp
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/lib/Sema/SemaType.cpp
clang/test/Sema/callingconv.c
clang/tools/libclang/CXType.cpp
Removed:
################################################################################
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index f28601c37d8ef..c4da7df6595d1 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -3445,6 +3445,7 @@ enum CXCallingConv {
CXCallingConv_PreserveAll = 15,
CXCallingConv_AArch64VectorCall = 16,
CXCallingConv_SwiftAsync = 17,
+ CXCallingConv_AArch64SVEPCS = 18,
CXCallingConv_Invalid = 100,
CXCallingConv_Unexposed = 200
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 39359f414ae78..3c41edb474e89 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2313,6 +2313,11 @@ def AArch64VectorPcs: DeclOrTypeAttr {
let Documentation = [AArch64VectorPcsDocs];
}
+def AArch64SVEPcs: DeclOrTypeAttr {
+ let Spellings = [Clang<"aarch64_sve_pcs">];
+ let Documentation = [AArch64SVEPcsDocs];
+}
+
def Pure : InheritableAttr {
let Spellings = [GCC<"pure">];
let Documentation = [Undocumented];
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index c7ef52f67afa3..b389ff9c02c45 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -2551,6 +2551,32 @@ the Arm Developer website.
}];
}
+def AArch64SVEPcsDocs : Documentation {
+ let Category = DocCatCallingConvs;
+ let Content = [{
+On AArch64 targets, this attribute changes the calling convention of a
+function to preserve additional Scalable Vector registers and Scalable
+Predicate registers relative to the default calling convention used for
+AArch64.
+
+This means it is more efficient to call such functions from code that performs
+extensive scalable vector and scalable predicate calculations, because fewer
+live SVE registers need to be saved. This property makes it well-suited for SVE
+math library functions, which are typically leaf functions that require a small
+number of registers.
+
+However, using this attribute also means that it is more expensive to call
+a function that adheres to the default calling convention from within such
+a function. Therefore, it is recommended that this attribute is only used
+for leaf functions.
+
+For more information, see the documentation for `aarch64_sve_pcs` in the
+ARM C Language Extension (ACLE) documentation.
+
+.. _`aarch64_sve_pcs`: https://github.com/ARM-software/acle/blob/main/main/acle.md#scalable-vector-extension-procedure-call-standard-attribute
+ }];
+}
+
def RegparmDocs : Documentation {
let Category = DocCatCallingConvs;
let Content = [{
diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h
index 52ca7cce9d961..7a727e7088deb 100644
--- a/clang/include/clang/Basic/Specifiers.h
+++ b/clang/include/clang/Basic/Specifiers.h
@@ -280,6 +280,7 @@ namespace clang {
CC_PreserveMost, // __attribute__((preserve_most))
CC_PreserveAll, // __attribute__((preserve_all))
CC_AArch64VectorCall, // __attribute__((aarch64_vector_pcs))
+ CC_AArch64SVEPCS, // __attribute__((aarch64_sve_pcs))
};
/// Checks whether the given calling convention supports variadic
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 8d90575385fc4..1be70487c1b4e 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3149,6 +3149,7 @@ StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) {
case CC_AAPCS:
case CC_AAPCS_VFP:
case CC_AArch64VectorCall:
+ case CC_AArch64SVEPCS:
case CC_IntelOclBicc:
case CC_SpirFunction:
case CC_OpenCLKernel:
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 92450e8f5f2f5..200a129437ed5 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -3185,6 +3185,7 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
case CC_AAPCS: return "aapcs";
case CC_AAPCS_VFP: return "aapcs-vfp";
case CC_AArch64VectorCall: return "aarch64_vector_pcs";
+ case CC_AArch64SVEPCS: return "aarch64_sve_pcs";
case CC_IntelOclBicc: return "intel_ocl_bicc";
case CC_SpirFunction: return "spir_function";
case CC_OpenCLKernel: return "opencl_kernel";
@@ -3620,6 +3621,7 @@ bool AttributedType::isCallingConv() const {
case attr::SwiftAsyncCall:
case attr::VectorCall:
case attr::AArch64VectorPcs:
+ case attr::AArch64SVEPcs:
case attr::Pascal:
case attr::MSABI:
case attr::SysVABI:
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 43183e1e5dd65..7bca45b5f5601 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -961,6 +961,9 @@ void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
case CC_AArch64VectorCall:
OS << "__attribute__((aarch64_vector_pcs))";
break;
+ case CC_AArch64SVEPCS:
+ OS << "__attribute__((aarch64_sve_pcs))";
+ break;
case CC_IntelOclBicc:
OS << " __attribute__((intel_ocl_bicc))";
break;
@@ -1750,6 +1753,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
break;
}
case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
+ case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
case attr::IntelOclBicc: OS << "inteloclbicc"; break;
case attr::PreserveMost:
OS << "preserve_most";
diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index f4aecd3675b1d..38862056227f1 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -676,6 +676,7 @@ AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
case CC_PreserveAll:
case CC_OpenCLKernel:
case CC_AArch64VectorCall:
+ case CC_AArch64SVEPCS:
case CC_Win64:
return CCCR_OK;
default:
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index d69455d650f43..a35e3d811862d 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -62,6 +62,7 @@ unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) {
// TODO: Add support for __vectorcall to LLVM.
case CC_X86VectorCall: return llvm::CallingConv::X86_VectorCall;
case CC_AArch64VectorCall: return llvm::CallingConv::AArch64_VectorCall;
+ case CC_AArch64SVEPCS: return llvm::CallingConv::AArch64_SVE_VectorCall;
case CC_SpirFunction: return llvm::CallingConv::SPIR_FUNC;
case CC_OpenCLKernel: return CGM.getTargetCodeGenInfo().getOpenCLKernelCallingConv();
case CC_PreserveMost: return llvm::CallingConv::PreserveMost;
@@ -228,6 +229,9 @@ static CallingConv getCallingConventionForDecl(const ObjCMethodDecl *D,
if (D->hasAttr<AArch64VectorPcsAttr>())
return CC_AArch64VectorCall;
+ if (D->hasAttr<AArch64SVEPcsAttr>())
+ return CC_AArch64SVEPCS;
+
if (D->hasAttr<IntelOclBiccAttr>())
return CC_IntelOclBicc;
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index a6ea2c0f31abf..3d73bfb8ce793 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1326,6 +1326,7 @@ static unsigned getDwarfCC(CallingConv CC) {
return llvm::dwarf::DW_CC_LLVM_X86_64SysV;
case CC_AAPCS:
case CC_AArch64VectorCall:
+ case CC_AArch64SVEPCS:
return llvm::dwarf::DW_CC_LLVM_AAPCS;
case CC_AAPCS_VFP:
return llvm::dwarf::DW_CC_LLVM_AAPCS_VFP;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 21001f8542477..c4a3b18ce2564 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5024,6 +5024,9 @@ static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
case ParsedAttr::AT_AArch64VectorPcs:
D->addAttr(::new (S.Context) AArch64VectorPcsAttr(S.Context, AL));
return;
+ case ParsedAttr::AT_AArch64SVEPcs:
+ D->addAttr(::new (S.Context) AArch64SVEPcsAttr(S.Context, AL));
+ return;
case ParsedAttr::AT_IntelOclBicc:
D->addAttr(::new (S.Context) IntelOclBiccAttr(S.Context, AL));
return;
@@ -5181,6 +5184,9 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
case ParsedAttr::AT_AArch64VectorPcs:
CC = CC_AArch64VectorCall;
break;
+ case ParsedAttr::AT_AArch64SVEPcs:
+ CC = CC_AArch64SVEPCS;
+ break;
case ParsedAttr::AT_RegCall:
CC = CC_X86RegCall;
break;
@@ -8793,6 +8799,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case ParsedAttr::AT_PreserveMost:
case ParsedAttr::AT_PreserveAll:
case ParsedAttr::AT_AArch64VectorPcs:
+ case ParsedAttr::AT_AArch64SVEPcs:
handleCallConvAttr(S, D, AL);
break;
case ParsedAttr::AT_Suppress:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 15f7d36840bad..0bb352e914a8c 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -121,6 +121,7 @@ static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr,
case ParsedAttr::AT_SwiftAsyncCall: \
case ParsedAttr::AT_VectorCall: \
case ParsedAttr::AT_AArch64VectorPcs: \
+ case ParsedAttr::AT_AArch64SVEPcs: \
case ParsedAttr::AT_MSABI: \
case ParsedAttr::AT_SysVABI: \
case ParsedAttr::AT_Pcs: \
@@ -7481,6 +7482,8 @@ static Attr *getCCTypeAttr(ASTContext &Ctx, ParsedAttr &Attr) {
return createSimpleAttr<VectorCallAttr>(Ctx, Attr);
case ParsedAttr::AT_AArch64VectorPcs:
return createSimpleAttr<AArch64VectorPcsAttr>(Ctx, Attr);
+ case ParsedAttr::AT_AArch64SVEPcs:
+ return createSimpleAttr<AArch64SVEPcsAttr>(Ctx, Attr);
case ParsedAttr::AT_Pcs: {
// The attribute may have had a fixit applied where we treated an
// identifier as a string literal. The contents of the string are valid,
diff --git a/clang/test/CodeGen/aarch64-svepcs.c b/clang/test/CodeGen/aarch64-svepcs.c
new file mode 100644
index 0000000000000..1d4e2f302e3f7
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-svepcs.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECKC
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -x c++ -o - %s | FileCheck %s -check-prefix=CHECKCXX
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -verify %s
+
+void __attribute__((aarch64_sve_pcs)) f(int *); // expected-warning {{'aarch64_sve_pcs' calling convention is not supported for this target}}
+
+// CHECKC: define{{.*}} void @g(
+// CHECKCXX: define{{.*}} void @_Z1gPi(
+void g(int *a) {
+
+ // CHECKC: call aarch64_sve_vector_pcs void @f(
+ // CHECKCXX: call aarch64_sve_vector_pcs void @_Z1fPi
+ f(a);
+}
+
+// CHECKC: declare aarch64_sve_vector_pcs void @f(
+// CHECKCXX: declare aarch64_sve_vector_pcs void @_Z1fPi
+
+void __attribute__((aarch64_sve_pcs)) h(int *a) { // expected-warning {{'aarch64_sve_pcs' calling convention is not supported for this target}}
+ // CHECKC: define{{.*}} aarch64_sve_vector_pcs void @h(
+ // CHECKCXX: define{{.*}} aarch64_sve_vector_pcs void @_Z1hPi(
+ f(a);
+}
diff --git a/clang/test/Sema/aarch64-svepcs.c b/clang/test/Sema/aarch64-svepcs.c
new file mode 100644
index 0000000000000..96661c80767fa
--- /dev/null
+++ b/clang/test/Sema/aarch64-svepcs.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +sve -verify %s
+
+typedef __attribute__((aarch64_sve_pcs)) int invalid_typedef; // expected-warning {{'aarch64_sve_pcs' only applies to function types; type here is 'int'}}
+
+void __attribute__((aarch64_sve_pcs(0))) foo0(void); // expected-error {{'aarch64_sve_pcs' attribute takes no arguments}}
+
+void __attribute__((aarch64_sve_pcs, preserve_all)) foo1(void); // expected-error {{not compatible}}
+
+void __attribute__((cdecl)) foo2(void); // expected-note {{previous declaration is here}}
+void __attribute__((aarch64_sve_pcs)) foo2(void) {} // expected-error {{function declared 'aarch64_sve_pcs' here was previously declared 'cdecl'}}
+
+void foo3(void); // expected-note {{previous declaration is here}}
+void __attribute__((aarch64_sve_pcs)) foo3(void) {} // expected-error {{function declared 'aarch64_sve_pcs' here was previously declared without calling convention}}
+
+typedef int (*fn_ty)(void);
+typedef int __attribute__((aarch64_sve_pcs)) (*aasvepcs_fn_ty)(void);
+void foo4(fn_ty ptr1, aasvepcs_fn_ty ptr2) {
+ ptr1 = ptr2; // expected-warning {{incompatible function pointer types}}
+}
diff --git a/clang/test/Sema/callingconv.c b/clang/test/Sema/callingconv.c
index ed8e60bc6c0b1..675200cc9cfc7 100644
--- a/clang/test/Sema/callingconv.c
+++ b/clang/test/Sema/callingconv.c
@@ -52,6 +52,7 @@ int __attribute__((pcs("aapcs-vfp"))) pcs6(void); // expected-warning {{'pcs' ca
int __attribute__((pcs("foo"))) pcs7(void); // expected-error {{invalid PCS type}}
int __attribute__((aarch64_vector_pcs)) aavpcs(void); // expected-warning {{'aarch64_vector_pcs' calling convention is not supported for this target}}
+int __attribute__((aarch64_sve_pcs)) aasvepcs(void); // expected-warning {{'aarch64_sve_pcs' calling convention is not supported for this target}}
// PR6361
void ctest3();
diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp
index 31a89426ec359..4aee32210df1f 100644
--- a/clang/tools/libclang/CXType.cpp
+++ b/clang/tools/libclang/CXType.cpp
@@ -666,6 +666,7 @@ CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
TCALLINGCONV(X86RegCall);
TCALLINGCONV(X86VectorCall);
TCALLINGCONV(AArch64VectorCall);
+ TCALLINGCONV(AArch64SVEPCS);
TCALLINGCONV(Win64);
TCALLINGCONV(X86_64SysV);
TCALLINGCONV(AAPCS);
More information about the cfe-commits
mailing list