[clang] [AArch64][ARM] Treat __bf16 as vendor extension type for C++ name mangling substitution (PR #115956)
Konstantin Schwarz via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 12 15:15:20 PST 2024
https://github.com/konstantinschwarz created https://github.com/llvm/llvm-project/pull/115956
This attempts to fix [#115521](https://github.com/llvm/llvm-project/issues/115521).
According to the Itanium C++ mangling rules, vendor extended builtin types are considered substitution candidates.
However, enabling this behavior on AArch64 and ARM is an ABI breaking change, and I'm not sure how problematic that is.
Note that gcc implements the same wrong behavior https://godbolt.org/z/1h4EcYrET
An alternative could be to detect the "u6__bf16" mangling in the demangler and specifically disable the substitution for this type.
>From 40ca031c0fd1b3e9997b2a2e0ed455233f781a9c Mon Sep 17 00:00:00 2001
From: Konstantin Schwarz <konstantin.schwarz at amd.com>
Date: Tue, 12 Nov 2024 21:47:33 +0000
Subject: [PATCH 1/2] [AArch64][ARM] Pre-commit mangling test for wrong __bf16
substitution behavior
---
clang/test/CodeGen/arm-mangle-bf16.cpp | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/clang/test/CodeGen/arm-mangle-bf16.cpp b/clang/test/CodeGen/arm-mangle-bf16.cpp
index 1d85c7b2733ac8..267fc5270f9387 100644
--- a/clang/test/CodeGen/arm-mangle-bf16.cpp
+++ b/clang/test/CodeGen/arm-mangle-bf16.cpp
@@ -2,6 +2,18 @@
// RUN: %clang_cc1 -triple aarch64 -target-feature -bf16 -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple arm-arm-none-eabi -target-feature +bf16 -mfloat-abi hard -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple arm-arm-none-eabi -target-feature +bf16 -mfloat-abi softfp -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64 -target-feature +bf16 -emit-llvm -o - %s | llvm-cxxfilt -n | FileCheck %s --check-prefix=DEMANGLE
+// RUN: %clang_cc1 -triple aarch64 -target-feature -bf16 -emit-llvm -o - %s | llvm-cxxfilt -n | FileCheck %s --check-prefix=DEMANGLE
+// RUN: %clang_cc1 -triple arm-arm-none-eabi -target-feature +bf16 -mfloat-abi hard -emit-llvm -o - %s | llvm-cxxfilt -n | FileCheck %s --check-prefix=DEMANGLE
+// RUN: %clang_cc1 -triple arm-arm-none-eabi -target-feature +bf16 -mfloat-abi softfp -emit-llvm -o - %s | llvm-cxxfilt -n | FileCheck %s --check-prefix=DEMANGLE
-// CHECK: define {{.*}}void @_Z3foou6__bf16(bfloat noundef %b)
+// CHECK: define {{.*}}void @_Z3foou6__bf16(bfloat noundef %b)
+// DEMANGLE: define {{.*}}void @foo(__bf16)
void foo(__bf16 b) {}
+
+struct bar;
+
+// CHECK: define {{.*}}void @_Z10substituteu6__bf16R3barS0_
+// DEMANGLE: define {{.*}}void @substitute(__bf16, bar&, bar)
+void substitute(__bf16 a, bar &b, bar &c) {
+}
>From 68609247bcd3cce8521337ad6a69acc4aa5f1a3b Mon Sep 17 00:00:00 2001
From: Konstantin Schwarz <konstantin.schwarz at amd.com>
Date: Tue, 12 Nov 2024 22:29:49 +0000
Subject: [PATCH 2/2] [AArch64][ARM] Treat __bf16 as vendor extension type for
C++ name mangling substitution
On AArch64 and ARM targets, __bf16 is mangled as "u6__bf16", which makes the type a vendor extended type.
According to the Itanium C++ mangling rules, such types are considered substitution candidates:
>From https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression:
"There are two exceptions that appear to be substitution candidates from the grammar, but are explicitly excluded:
- <builtin-type> other than vendor extended types
- function and operator names other than extern "C" functions."
This attempts to fix #115521
---
clang/include/clang/Basic/TargetInfo.h | 4 ++++
clang/lib/AST/ItaniumMangle.cpp | 9 +++++++++
clang/lib/Basic/Targets/AArch64.h | 3 +++
clang/lib/Basic/Targets/ARM.h | 2 ++
.../AArch64/sve-intrinsics/acle_sve_dupq-bfloat.c | 2 +-
.../AArch64/sve2-intrinsics/acle_sve2_whilerw-bfloat.c | 2 +-
.../AArch64/sve2-intrinsics/acle_sve2_whilewr-bfloat.c | 2 +-
clang/test/CodeGen/arm-mangle-bf16.cpp | 4 ++--
8 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 25eda907d20a7b..d4456c83a0eefa 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -810,6 +810,10 @@ class TargetInfo : public TransferrableTargetInfo,
/// Return the mangled code of bfloat.
virtual const char *getBFloat16Mangling() const { return "DF16b"; }
+ /// Returns whether to treat bfloat as a vendor extension type for the purpose
+ /// of Itanium C++ name mangling compression rules
+ virtual bool treatBFloat16AsVendorType() const { return false; }
+
/// Return the value for the C99 FLT_EVAL_METHOD macro.
virtual LangOptions::FPEvalMethodKind getFPEvalMethod() const {
return LangOptions::FPEvalMethodKind::FEM_Source;
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 14bc260d0245fb..30164ad5ebbd7f 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -2923,6 +2923,15 @@ static bool isTypeSubstitutable(Qualifiers Quals, const Type *Ty,
return true;
if (Ty->isSpecificBuiltinType(BuiltinType::ObjCSel))
return true;
+ if (Ty->isSpecificBuiltinType(BuiltinType::BFloat16)) {
+ const TargetInfo *TI =
+ Ctx.getLangOpts().OpenMP && Ctx.getLangOpts().OpenMPIsTargetDevice
+ ? Ctx.getAuxTargetInfo()
+ : &Ctx.getTargetInfo();
+ // Some targets mangle bfloat16 as a vendor extension type, thus making them
+ // candidates for substitution
+ return TI->treatBFloat16AsVendorType();
+ }
if (Ty->isOpenCLSpecificType())
return true;
// From Clang 18.0 we correctly treat SVE types as substitution candidates.
diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h
index ea3e4015d84265..55a9f9d076b2bd 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -227,6 +227,9 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
bool validatePointerAuthKey(const llvm::APSInt &value) const override;
const char *getBFloat16Mangling() const override { return "u6__bf16"; };
+
+ bool treatBFloat16AsVendorType() const override { return true; }
+
bool hasInt128Type() const override;
bool hasBitIntType() const override { return true; }
diff --git a/clang/lib/Basic/Targets/ARM.h b/clang/lib/Basic/Targets/ARM.h
index 55ecb99d82d8fb..6455557f11691d 100644
--- a/clang/lib/Basic/Targets/ARM.h
+++ b/clang/lib/Basic/Targets/ARM.h
@@ -226,6 +226,8 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
const char *getBFloat16Mangling() const override { return "u6__bf16"; };
+ bool treatBFloat16AsVendorType() const override { return true; }
+
std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(getTriple().isArch64Bit() ? 256 : 64, 64);
}
diff --git a/clang/test/CodeGen/AArch64/sve-intrinsics/acle_sve_dupq-bfloat.c b/clang/test/CodeGen/AArch64/sve-intrinsics/acle_sve_dupq-bfloat.c
index 45e30aa20f29a7..2d533642446152 100644
--- a/clang/test/CodeGen/AArch64/sve-intrinsics/acle_sve_dupq-bfloat.c
+++ b/clang/test/CodeGen/AArch64/sve-intrinsics/acle_sve_dupq-bfloat.c
@@ -51,7 +51,7 @@ svbfloat16_t test_svdupq_lane_bf16(svbfloat16_t data, uint64_t index) MODE_ATTR
// CHECK-NEXT: [[TMP9:%.*]] = tail call <vscale x 8 x bfloat> @llvm.aarch64.sve.dupq.lane.nxv8bf16(<vscale x 8 x bfloat> [[TMP8]], i64 0)
// CHECK-NEXT: ret <vscale x 8 x bfloat> [[TMP9]]
//
-// CPP-CHECK-LABEL: @_Z18test_svdupq_n_bf16u6__bf16u6__bf16u6__bf16u6__bf16u6__bf16u6__bf16u6__bf16u6__bf16(
+// CPP-CHECK-LABEL: @_Z18test_svdupq_n_bf16u6__bf16S_S_S_S_S_S_S_(
// CPP-CHECK-NEXT: entry:
// CPP-CHECK-NEXT: [[TMP0:%.*]] = insertelement <8 x bfloat> poison, bfloat [[X0:%.*]], i64 0
// CPP-CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x bfloat> [[TMP0]], bfloat [[X1:%.*]], i64 1
diff --git a/clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_whilerw-bfloat.c b/clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_whilerw-bfloat.c
index 95b0f53abdce0f..030a475d9cb22a 100644
--- a/clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_whilerw-bfloat.c
+++ b/clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_whilerw-bfloat.c
@@ -21,7 +21,7 @@
// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv8i1(<vscale x 8 x i1> [[TMP0]])
// CHECK-NEXT: ret <vscale x 16 x i1> [[TMP1]]
//
-// CPP-CHECK-LABEL: @_Z19test_svwhilerw_bf16PKu6__bf16S0_(
+// CPP-CHECK-LABEL: @_Z19test_svwhilerw_bf16PKu6__bf16S1_(
// CPP-CHECK-NEXT: entry:
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.whilerw.h.nxv8i1.p0(ptr [[OP1:%.*]], ptr [[OP2:%.*]])
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv8i1(<vscale x 8 x i1> [[TMP0]])
diff --git a/clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_whilewr-bfloat.c b/clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_whilewr-bfloat.c
index 647f2aef98d812..32bbf58dd11500 100644
--- a/clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_whilewr-bfloat.c
+++ b/clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_whilewr-bfloat.c
@@ -21,7 +21,7 @@
// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv8i1(<vscale x 8 x i1> [[TMP0]])
// CHECK-NEXT: ret <vscale x 16 x i1> [[TMP1]]
//
-// CPP-CHECK-LABEL: @_Z19test_svwhilewr_bf16PKu6__bf16S0_(
+// CPP-CHECK-LABEL: @_Z19test_svwhilewr_bf16PKu6__bf16S1_(
// CPP-CHECK-NEXT: entry:
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.whilewr.h.nxv8i1.p0(ptr [[OP1:%.*]], ptr [[OP2:%.*]])
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv8i1(<vscale x 8 x i1> [[TMP0]])
diff --git a/clang/test/CodeGen/arm-mangle-bf16.cpp b/clang/test/CodeGen/arm-mangle-bf16.cpp
index 267fc5270f9387..36fbe828b9a7a5 100644
--- a/clang/test/CodeGen/arm-mangle-bf16.cpp
+++ b/clang/test/CodeGen/arm-mangle-bf16.cpp
@@ -13,7 +13,7 @@ void foo(__bf16 b) {}
struct bar;
-// CHECK: define {{.*}}void @_Z10substituteu6__bf16R3barS0_
-// DEMANGLE: define {{.*}}void @substitute(__bf16, bar&, bar)
+// CHECK: define {{.*}}void @_Z10substituteu6__bf16R3barS1_
+// DEMANGLE: define {{.*}}void @substitute(__bf16, bar&, bar&)
void substitute(__bf16 a, bar &b, bar &c) {
}
More information about the cfe-commits
mailing list