[clang] [AArch64] Add support for MSVC-style mangling for SVE (PR #196738)
Edward Nathan Varghese via cfe-commits
cfe-commits at lists.llvm.org
Sat May 9 10:33:43 PDT 2026
https://github.com/edwardnvv57k updated https://github.com/llvm/llvm-project/pull/196738
>From 7a87d5d0762175551fcbde17eee7060ef558bc4c Mon Sep 17 00:00:00 2001
From: Edward Nathan Varghese <edwardnvarghese at gmail.com>
Date: Sat, 9 May 2026 22:45:11 +0530
Subject: [PATCH] [AArch64] Add support for MSVC-style mangling for SVE
---
clang/lib/AST/MicrosoftMangle.cpp | 199 +++++++++++++++++-
.../aarch64-mangle-sve-vectors-msvc.cpp | 58 ++++-
2 files changed, 243 insertions(+), 14 deletions(-)
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 7d0c60d57253c..579387e16e3a9 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -2831,14 +2831,201 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
break;
#include "clang/Basic/HLSLIntangibleTypes.def"
-#define SVE_TYPE(Name, Id, SingletonId) \
- case BuiltinType::Id: \
- mangleArtificialTagType(TagTypeKind::Struct, #Name, {"__clang"}); \
+ case BuiltinType::SveBool:
+ Out << "$_CA";
+ break;
+
+ case BuiltinType::SveInt8:
+ Out << "$_CB";
+ break;
+ case BuiltinType::SveInt16:
+ Out << "$_CC";
+ break;
+ case BuiltinType::SveInt32:
+ Out << "$_CD";
+ break;
+ case BuiltinType::SveInt64:
+ Out << "$_CE";
+ break;
+
+ case BuiltinType::SveUint8:
+ Out << "$_CF";
+ break;
+ case BuiltinType::SveUint16:
+ Out << "$_CG";
+ break;
+ case BuiltinType::SveUint32:
+ Out << "$_CH";
+ break;
+ case BuiltinType::SveUint64:
+ Out << "$_CI";
+ break;
+
+ case BuiltinType::SveBFloat16:
+ Out << "$_CJ";
+ break;
+ case BuiltinType::SveFloat16:
+ Out << "$_CK";
+ break;
+ case BuiltinType::SveFloat32:
+ Out << "$_CL";
+ break;
+ case BuiltinType::SveFloat64:
+ Out << "$_CM";
+ break;
+
+ case BuiltinType::SveInt8x2:
+ Out << "$_C2B";
+ break;
+ case BuiltinType::SveInt16x2:
+ Out << "$_C2C";
+ break;
+ case BuiltinType::SveInt32x2:
+ Out << "$_C2D";
+ break;
+ case BuiltinType::SveInt64x2:
+ Out << "$_C2E";
+ break;
+
+ case BuiltinType::SveUint8x2:
+ Out << "$_C2F";
+ break;
+ case BuiltinType::SveUint16x2:
+ Out << "$_C2G";
+ break;
+ case BuiltinType::SveUint32x2:
+ Out << "$_C2H";
+ break;
+ case BuiltinType::SveUint64x2:
+ Out << "$_C2I";
+ break;
+
+ case BuiltinType::SveBFloat16x2:
+ Out << "$_C2J";
+ break;
+ case BuiltinType::SveFloat16x2:
+ Out << "$_C2K";
+ break;
+ case BuiltinType::SveFloat32x2:
+ Out << "$_C2L";
+ break;
+ case BuiltinType::SveFloat64x2:
+ Out << "$_C2M";
+ break;
+
+ case BuiltinType::SveInt8x3:
+ Out << "$_C3B";
+ break;
+ case BuiltinType::SveInt16x3:
+ Out << "$_C3C";
+ break;
+ case BuiltinType::SveInt32x3:
+ Out << "$_C3D";
+ break;
+ case BuiltinType::SveInt64x3:
+ Out << "$_C3E";
+ break;
+
+ case BuiltinType::SveUint8x3:
+ Out << "$_C3F";
+ break;
+ case BuiltinType::SveUint16x3:
+ Out << "$_C3G";
+ break;
+ case BuiltinType::SveUint32x3:
+ Out << "$_C3H";
+ break;
+ case BuiltinType::SveUint64x3:
+ Out << "$_C3I";
+ break;
+
+ case BuiltinType::SveBFloat16x3:
+ Out << "$_C3J";
+ break;
+ case BuiltinType::SveFloat16x3:
+ Out << "$_C3K";
+ break;
+ case BuiltinType::SveFloat32x3:
+ Out << "$_C3L";
+ break;
+ case BuiltinType::SveFloat64x3:
+ Out << "$_C3M";
+ break;
+
+ case BuiltinType::SveInt8x4:
+ Out << "$_C4B";
+ break;
+ case BuiltinType::SveInt16x4:
+ Out << "$_C4C";
+ break;
+ case BuiltinType::SveInt32x4:
+ Out << "$_C4D";
+ break;
+ case BuiltinType::SveInt64x4:
+ Out << "$_C4E";
+ break;
+
+ case BuiltinType::SveUint8x4:
+ Out << "$_C4F";
+ break;
+ case BuiltinType::SveUint16x4:
+ Out << "$_C4G";
+ break;
+ case BuiltinType::SveUint32x4:
+ Out << "$_C4H";
+ break;
+ case BuiltinType::SveUint64x4:
+ Out << "$_C4I";
+ break;
+
+ case BuiltinType::SveBFloat16x4:
+ Out << "$_C4J";
+ break;
+ case BuiltinType::SveFloat16x4:
+ Out << "$_C4K";
+ break;
+ case BuiltinType::SveFloat32x4:
+ Out << "$_C4L";
+ break;
+ case BuiltinType::SveFloat64x4:
+ Out << "$_C4M";
+ break;
+
+ // Unsupported SVE types still use the legacy artificial tag mangling
+ case BuiltinType::SveMFloat8:
+ mangleArtificialTagType(TagTypeKind::Struct, "__SVMfloat8_t", {"__clang"});
+ break;
+
+ case BuiltinType::SveMFloat8x2:
+ mangleArtificialTagType(TagTypeKind::Struct, "__clang_svmfloat8x2_t",
+ {"__clang"});
+ break;
+
+ case BuiltinType::SveMFloat8x3:
+ mangleArtificialTagType(TagTypeKind::Struct, "__clang_svmfloat8x3_t",
+ {"__clang"});
+ break;
+
+ case BuiltinType::SveMFloat8x4:
+ mangleArtificialTagType(TagTypeKind::Struct, "__clang_svmfloat8x4_t",
+ {"__clang"});
+ break;
+
+ case BuiltinType::SveBoolx2:
+ mangleArtificialTagType(TagTypeKind::Struct, "__clang_svboolx2_t",
+ {"__clang"});
+ break;
+
+ case BuiltinType::SveBoolx4:
+ mangleArtificialTagType(TagTypeKind::Struct, "__clang_svboolx4_t",
+ {"__clang"});
+ break;
+
+ case BuiltinType::SveCount:
+ mangleArtificialTagType(TagTypeKind::Struct, "__SVCount_t", {"__clang"});
break;
-#define SVE_SCALAR_TYPE(Name, MangledName, Id, SingletonId, Bits)
-#include "clang/Basic/AArch64ACLETypes.def"
- // Issue an error for any type not explicitly handled.
+ // Issue an error for any type not explicitly handled.
default:
Error(Range.getBegin(), "built-in type: ",
T->getName(Context.getASTContext().getPrintingPolicy()))
diff --git a/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors-msvc.cpp b/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors-msvc.cpp
index 3ed75b9494c2a..2b2e1648184d2 100644
--- a/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors-msvc.cpp
+++ b/clang/test/CodeGenCXX/aarch64-mangle-sve-vectors-msvc.cpp
@@ -1,13 +1,55 @@
-// RUN: %clang_cc1 -triple aarch64-unknown-windows-msvc %s -emit-llvm \
-// RUN: -o - | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-unknown-windows-msvc \
+// RUN: -target-feature +sve -emit-llvm -o - %s | FileCheck %s
-template<typename T> struct S {};
+template <typename T> struct S {};
-// CHECK: void @"?f1@@YAXU?$S at U__SVInt8_t@__clang@@@@@Z"
+// Scalar SVE types.
+
+// CHECK: void @"?f1@@YAXU?$S@$_CB@@@Z"
void f1(S<__SVInt8_t>) {}
-// CHECK: void @"?f2@@YAXU?$S at U__SVInt32_t@__clang@@@@@Z"
+
+// CHECK: void @"?f2@@YAXU?$S@$_CD@@@Z"
void f2(S<__SVInt32_t>) {}
-// CHECK: void @"?f3@@YAXU?$S at U__SVBool_t@__clang@@@@@Z"
+
+// CHECK: void @"?f3@@YAXU?$S@$_CA@@@Z"
void f3(S<__SVBool_t>) {}
-// CHECK: void @"?f4@@YAXU?$S at U__clang_svfloat64x4_t@__clang@@@@@Z"
-void f4(S<__clang_svfloat64x4_t>) {}
+
+// CHECK: void @"?f4@@YAXU?$S@$_CH@@@Z"
+void f4(S<__SVUint32_t>) {}
+
+// CHECK: void @"?f5@@YAXU?$S@$_CL@@@Z"
+void f5(S<__SVFloat32_t>) {}
+
+// CHECK: void @"?f13@@YAXU?$S@$_CJ@@@Z"
+void f13(S<__SVBfloat16_t>) {}
+
+// Tuple SVE types.
+
+// CHECK: void @"?f6@@YAXU?$S@$_C2B@@@Z"
+void f6(S<__clang_svint8x2_t>) {}
+
+// CHECK: void @"?f7@@YAXU?$S@$_C3B@@@Z"
+void f7(S<__clang_svint8x3_t>) {}
+
+// CHECK: void @"?f8@@YAXU?$S@$_C4B@@@Z"
+void f8(S<__clang_svint8x4_t>) {}
+
+// CHECK: void @"?f9@@YAXU?$S@$_C4M@@@Z"
+void f9(S<__clang_svfloat64x4_t>) {}
+
+// CHECK: void @"?f14@@YAXU?$S@$_C2H@@@Z"
+void f14(S<__clang_svuint32x2_t>) {}
+
+// CHECK: void @"?f15@@YAXU?$S@$_C3L@@@Z"
+void f15(S<__clang_svfloat32x3_t>) {}
+
+// Unsupported types should continue using legacy artificial tag mangling.
+
+// CHECK: void @"?f10@@YAXU?$S at U__SVMfloat8_t@__clang@@@@@Z"
+void f10(S<__SVMfloat8_t>) {}
+
+// CHECK: void @"?f11@@YAXU?$S at U__clang_svboolx2_t@__clang@@@@@Z"
+void f11(S<__clang_svboolx2_t>) {}
+
+// CHECK: void @"?f12@@YAXU?$S at U__SVCount_t@__clang@@@@@Z"
+void f12(S<__SVCount_t>) {}
\ No newline at end of file
More information about the cfe-commits
mailing list