[clang] [Clang][AArch64] Include SME attributes in the name mangling of function types (PR #114209)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 25 07:46:59 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Kerry McLaughlin (kmclaughlin-arm)
<details>
<summary>Changes</summary>
Similar to arm_sve_vector_bits, the mangling of function types is implemented as a pseudo template if there are any SME attributes present, i.e.
`__SME_ATTRS<normal_function_type, sme_state>`
For example, the following function:
`void f(svint8_t (*fn)() __arm_streaming) { fn(); }`
would be mangled as:
`_Z1fP11__SME_ATTRSIFu10__SVInt8_tELj1EE`
See https://github.com/ARM-software/acle/pull/358
---
Full diff: https://github.com/llvm/llvm-project/pull/114209.diff
2 Files Affected:
- (modified) clang/lib/AST/ItaniumMangle.cpp (+70)
- (added) clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp (+74)
``````````diff
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index b3e46508cf596d..23c8f255c7c16e 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -575,6 +575,7 @@ class CXXNameMangler {
static StringRef getCallingConvQualifierName(CallingConv CC);
void mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo info);
void mangleExtFunctionInfo(const FunctionType *T);
+ void mangleSMEAttrs(unsigned SMEAttrs);
void mangleBareFunctionType(const FunctionProtoType *T, bool MangleReturnType,
const FunctionDecl *FD = nullptr);
void mangleNeonVectorType(const VectorType *T);
@@ -3535,6 +3536,68 @@ void CXXNameMangler::mangleExtFunctionInfo(const FunctionType *T) {
// FIXME: noreturn
}
+unsigned getZAState(unsigned SMEAttrs) {
+ switch (SMEAttrs) {
+ case FunctionType::ARM_In:
+ return 1;
+ case FunctionType::ARM_Out:
+ return 2;
+ case FunctionType::ARM_InOut:
+ return 3;
+ case FunctionType::ARM_Preserves:
+ return 4;
+ default:
+ return 0;
+ }
+}
+
+// The mangling scheme for function types which have SME attributes is implemented as
+// a "pseudo" template:
+//
+// '__SME_ATTRS<<normal_function_type>, <sme_state>>'
+//
+// Combining the function type with a bitmask representing the streaming and ZA properties
+// of the function's interface. The bits of sme_state are defined as follows:
+// 0: Streaming Mode
+// 1: Streaming Compatible
+// 2: ZA Agnostic
+// 3-5: ZA State
+// 6-8: ZT0 State
+// 9-63: 0, reserved for future type attributes.
+//
+// For example:
+// void f(svint8_t (*fn)() __arm_streaming_compatible __arm_inout("za")) { fn(); }
+//
+// The function fn is described as '__SME_ATTRS<Fu10__SVInt8_tvE, 26u>' and mangled as:
+//
+// "11__SME_ATTRSI" + function type mangling + "Lj" + bitmask + "EE"
+//
+// i.e. "11__SME_ATTRSIFu10__SVInt8_tvELj26EE"
+//
+void CXXNameMangler::mangleSMEAttrs(unsigned SMEAttrs) {
+ if (!SMEAttrs)
+ return;
+
+ // Streaming Mode
+ unsigned Bitmask = 0;
+ if (SMEAttrs & FunctionType::SME_PStateSMEnabledMask)
+ Bitmask |= 1;
+ else if (SMEAttrs & FunctionType::SME_PStateSMCompatibleMask)
+ Bitmask |= 1 << 1;
+
+ // TODO: Must represent __arm_agnostic("sme_za_state")
+
+ // ZA-State
+ Bitmask |= getZAState(FunctionType::getArmZAState(SMEAttrs)) << 3;
+
+ // ZT0 State
+ Bitmask |= getZAState(FunctionType::getArmZT0State(SMEAttrs)) << 6;
+
+ Out << "Lj" << Bitmask << "EE";
+
+ return;
+}
+
void
CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) {
// Vendor-specific qualifiers are emitted in reverse alphabetical order.
@@ -3572,6 +3635,11 @@ CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) {
// <function-type> ::= [<CV-qualifiers>] F [Y]
// <bare-function-type> [<ref-qualifier>] E
void CXXNameMangler::mangleType(const FunctionProtoType *T) {
+ unsigned SMEAttrs = T->getAArch64SMEAttributes();
+
+ if (SMEAttrs)
+ Out << "11__SME_ATTRSI";
+
mangleExtFunctionInfo(T);
// Mangle CV-qualifiers, if present. These are 'this' qualifiers,
@@ -3606,6 +3674,8 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) {
mangleRefQualifier(T->getRefQualifier());
Out << 'E';
+
+ mangleSMEAttrs(SMEAttrs);
}
void CXXNameMangler::mangleType(const FunctionNoProtoType *T) {
diff --git a/clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp b/clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp
new file mode 100644
index 00000000000000..09db59ac621a22
--- /dev/null
+++ b/clang/test/CodeGenCXX/aarch64-mangle-sme-atts.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme -target-feature +sme2 %s -emit-llvm -o - | FileCheck %s
+
+typedef __attribute__((neon_vector_type(2))) int int32x2_t;
+
+//
+// Streaming-Mode Attributes
+//
+
+// CHECK: define dso_local void @_Z12fn_streamingP11__SME_ATTRSIFvvELj1EE
+void fn_streaming(void (*foo)() __arm_streaming) { foo(); }
+
+// CHECK: define dso_local void @_Z23fn_streaming_compatibleP11__SME_ATTRSIFivELj2EE(
+void fn_streaming_compatible(int (*foo)() __arm_streaming_compatible) { foo(); }
+
+//
+// ZA Attributes
+//
+
+// CHECK: define dso_local void @_Z15fn_za_preservedP11__SME_ATTRSIF11__Int32x2_tvELj32EE(
+__arm_new("za") void fn_za_preserved(int32x2_t (*foo)() __arm_preserves("za")) { foo(); }
+
+// CHECK: define dso_local void @_Z8fn_za_inP11__SME_ATTRSIFvu13__SVFloat64_tELj8EES_(
+__arm_new("za") void fn_za_in(void (*foo)(__SVFloat64_t) __arm_in("za"), __SVFloat64_t x) { foo(x); }
+
+// CHECK: define dso_local noundef i32 @_Z9fn_za_outP11__SME_ATTRSIFivELj16EE(
+__arm_new("za") int fn_za_out(int (*foo)() __arm_out("za")) { return foo(); }
+
+// CHECK: define dso_local void @_Z11fn_za_inoutP11__SME_ATTRSIFvvELj24EE(
+__arm_new("za") void fn_za_inout(void (*foo)() __arm_inout("za")) { foo(); }
+
+
+//
+// ZT0 Attributes
+//
+
+// CHECK: define dso_local void @_Z16fn_zt0_preservedP11__SME_ATTRSIFivELj256EE(
+__arm_new("zt0") void fn_zt0_preserved(int (*foo)() __arm_preserves("zt0")) { foo(); }
+
+// CHECK: define dso_local void @_Z9fn_zt0_inP11__SME_ATTRSIFivELj64EE(
+__arm_new("zt0") void fn_zt0_in(int (*foo)() __arm_in("zt0")) { foo(); }
+
+// CHECK: define dso_local void @_Z10fn_zt0_outP11__SME_ATTRSIFivELj128EE(
+__arm_new("zt0") void fn_zt0_out(int (*foo)() __arm_out("zt0")) { foo(); }
+
+// CHECK: define dso_local void @_Z12fn_zt0_inoutP11__SME_ATTRSIFivELj192EE(
+__arm_new("zt0") void fn_zt0_inout(int (*foo)() __arm_inout("zt0")) { foo(); }
+
+//
+// Streaming-mode, ZA & ZT0 Attributes
+//
+
+// CHECK: define dso_local void @_Z17fn_all_attr_typesP11__SME_ATTRSIFivELj282EE(
+__arm_new("za") __arm_new("zt0")
+void fn_all_attr_types(int (*foo)() __arm_streaming_compatible __arm_inout("za") __arm_preserves("zt0"))
+{ foo(); }
+
+//
+// No SME Attributes
+//
+
+// CHECK: define dso_local void @_Z12no_sme_attrsPFvvE(
+void no_sme_attrs(void (*foo)()) { foo(); }
+
+// CHECK: define dso_local void @_Z24locally_streaming_callerPFvvE(
+__arm_locally_streaming void locally_streaming_caller(void (*foo)()) { foo(); }
+
+// CHECK: define dso_local void @_Z16streaming_callerv(
+void streaming_caller() __arm_streaming {}
+
+// CHECK: define dso_local void @_Z16za_shared_callerv(
+void za_shared_caller() __arm_in("za") {}
+
+// CHECK: define dso_local void @_Z17zt0_shared_callerv(
+void zt0_shared_caller() __arm_out("zt0") {}
``````````
</details>
https://github.com/llvm/llvm-project/pull/114209
More information about the cfe-commits
mailing list