[clang] [AArch64][ARM] Treat __bf16 as vendor extension type for C++ name mangling substitution (PR #115956)

via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 12 15:16:00 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64

@llvm/pr-subscribers-clang

Author: Konstantin Schwarz (konstantinschwarz)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/115956.diff


8 Files Affected:

- (modified) clang/include/clang/Basic/TargetInfo.h (+4) 
- (modified) clang/lib/AST/ItaniumMangle.cpp (+9) 
- (modified) clang/lib/Basic/Targets/AArch64.h (+3) 
- (modified) clang/lib/Basic/Targets/ARM.h (+2) 
- (modified) clang/test/CodeGen/AArch64/sve-intrinsics/acle_sve_dupq-bfloat.c (+1-1) 
- (modified) clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_whilerw-bfloat.c (+1-1) 
- (modified) clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_whilewr-bfloat.c (+1-1) 
- (modified) clang/test/CodeGen/arm-mangle-bf16.cpp (+13-1) 


``````````diff
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 1d85c7b2733ac8..36fbe828b9a7a5 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__bf16R3barS1_
+// DEMANGLE: define {{.*}}void @substitute(__bf16, bar&, bar&)
+void substitute(__bf16 a, bar &b, bar &c) {
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/115956


More information about the cfe-commits mailing list