Skip to content

Commit b8cd348

Browse files
authored
Add clang patch to enable BFloat16 for SPIR/SPIR-V (#585)
1 parent 18ec882 commit b8cd348

File tree

2 files changed

+213
-0
lines changed

2 files changed

+213
-0
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
From fb1c11f76ee840c6dc776638dbd822d8fe311107 Mon Sep 17 00:00:00 2001
2+
From: Wenju He <[email protected]>
3+
Date: Fri, 21 Nov 2025 04:49:55 +0100
4+
Subject: [PATCH 1/2] [Clang][BFloat16] Upgrade __bf16 to arithmetic type,
5+
change mangling, and extend excess precision support
6+
7+
Pursuant to discussions at
8+
https://discourse.llvm.org/t/rfc-c-23-p1467r9-extended-floating-point-types-and-standard-names/70033/22,
9+
this commit enhances the handling of the __bf16 type in Clang.
10+
- Firstly, it upgrades __bf16 from a storage-only type to an arithmetic
11+
type.
12+
- Secondly, it changes the mangling of __bf16 to DF16b on all
13+
architectures except ARM. This change has been made in
14+
accordance with the finalization of the mangling for the
15+
std::bfloat16_t type, as discussed at
16+
https://github.com/itanium-cxx-abi/cxx-abi/pull/147.
17+
- Finally, this commit extends the existing excess precision support to
18+
the __bf16 type. This applies to hardware architectures that do not
19+
natively support bfloat16 arithmetic.
20+
Appropriate tests have been added to verify the effects of these
21+
changes and ensure no regressions in other areas of the compiler.
22+
23+
Reviewed By: rjmccall, pengfei, zahiraam
24+
25+
Differential Revision: https://reviews.llvm.org/D150913
26+
27+
(partially cherry picked from commit e62175736551abf40a3410bc246f58e650eb8158)
28+
---
29+
clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 --
30+
clang/include/clang/Basic/TargetInfo.h | 15 +++++++++++----
31+
clang/lib/AST/Type.cpp | 3 +--
32+
clang/lib/Basic/TargetInfo.cpp | 1 +
33+
clang/lib/Sema/SemaCast.cpp | 14 --------------
34+
clang/lib/Sema/SemaExpr.cpp | 4 ----
35+
clang/lib/Sema/SemaOverload.cpp | 10 +++++-----
36+
7 files changed, 18 insertions(+), 31 deletions(-)
37+
38+
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
39+
index a8cf00c1263f..895411e49d1d 100644
40+
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
41+
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
42+
@@ -8584,8 +8584,6 @@ def warn_cast_function_type : Warning<
43+
InGroup<CastFunctionType>, DefaultIgnore;
44+
def err_cast_pointer_to_non_pointer_int : Error<
45+
"pointer cannot be cast to type %0">;
46+
-def err_cast_to_bfloat16 : Error<"cannot type-cast to __bf16">;
47+
-def err_cast_from_bfloat16 : Error<"cannot type-cast from __bf16">;
48+
def err_typecheck_expect_scalar_operand : Error<
49+
"operand of type %0 where arithmetic or pointer type is required">;
50+
def err_typecheck_cond_incompatible_operands : Error<
51+
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
52+
index e7db877f4e2b..7804eb01f079 100644
53+
--- a/clang/include/clang/Basic/TargetInfo.h
54+
+++ b/clang/include/clang/Basic/TargetInfo.h
55+
@@ -199,6 +199,9 @@ protected:
56+
bool HasFloat128;
57+
bool HasFloat16;
58+
bool HasBFloat16;
59+
+ bool HasFullBFloat16; // True if the backend supports native bfloat16
60+
+ // arithmetic. Used to determine excess precision
61+
+ // support in the frontend.
62+
bool HasIbm128;
63+
bool HasLongDouble;
64+
bool HasFPReturn;
65+
@@ -611,7 +614,13 @@ public:
66+
virtual bool hasFloat16Type() const { return HasFloat16; }
67+
68+
/// Determine whether the _BFloat16 type is supported on this target.
69+
- virtual bool hasBFloat16Type() const { return HasBFloat16; }
70+
+ virtual bool hasBFloat16Type() const {
71+
+ return HasBFloat16 || HasFullBFloat16;
72+
+ }
73+
+
74+
+ /// Determine whether the BFloat type is fully supported on this target, i.e
75+
+ /// arithemtic operations.
76+
+ virtual bool hasFullBFloat16Type() const { return HasFullBFloat16; }
77+
78+
/// Determine whether the __ibm128 type is supported on this target.
79+
virtual bool hasIbm128Type() const { return HasIbm128; }
80+
@@ -719,9 +728,7 @@ public:
81+
}
82+
83+
/// Return the mangled code of bfloat.
84+
- virtual const char *getBFloat16Mangling() const {
85+
- llvm_unreachable("bfloat not implemented on this target");
86+
- }
87+
+ virtual const char *getBFloat16Mangling() const { return "DF16b"; }
88+
89+
/// Return the value for the C99 FLT_EVAL_METHOD macro.
90+
virtual unsigned getFloatEvalMethod() const { return 0; }
91+
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
92+
index 774b3e94159d..d3a69472cec6 100644
93+
--- a/clang/lib/AST/Type.cpp
94+
+++ b/clang/lib/AST/Type.cpp
95+
@@ -2142,8 +2142,7 @@ bool Type::isRealType() const {
96+
bool Type::isArithmeticType() const {
97+
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
98+
return BT->getKind() >= BuiltinType::Bool &&
99+
- BT->getKind() <= BuiltinType::Ibm128 &&
100+
- BT->getKind() != BuiltinType::BFloat16;
101+
+ BT->getKind() <= BuiltinType::Ibm128;
102+
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
103+
// GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2).
104+
// If a body isn't seen by the time we get here, return false.
105+
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
106+
index 188ffb5f2f78..d98288d74df2 100644
107+
--- a/clang/lib/Basic/TargetInfo.cpp
108+
+++ b/clang/lib/Basic/TargetInfo.cpp
109+
@@ -37,6 +37,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
110+
HasIbm128 = false;
111+
HasFloat16 = false;
112+
HasBFloat16 = false;
113+
+ HasFullBFloat16 = false;
114+
HasLongDouble = true;
115+
HasFPReturn = true;
116+
HasStrictFP = false;
117+
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
118+
index 7ef1732496c2..fc6dfc3236d2 100644
119+
--- a/clang/lib/Sema/SemaCast.cpp
120+
+++ b/clang/lib/Sema/SemaCast.cpp
121+
@@ -3028,20 +3028,6 @@ void CastOperation::CheckCStyleCast() {
122+
return;
123+
}
124+
125+
- // Can't cast to or from bfloat
126+
- if (DestType->isBFloat16Type() && !SrcType->isBFloat16Type()) {
127+
- Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_to_bfloat16)
128+
- << SrcExpr.get()->getSourceRange();
129+
- SrcExpr = ExprError();
130+
- return;
131+
- }
132+
- if (SrcType->isBFloat16Type() && !DestType->isBFloat16Type()) {
133+
- Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_from_bfloat16)
134+
- << SrcExpr.get()->getSourceRange();
135+
- SrcExpr = ExprError();
136+
- return;
137+
- }
138+
-
139+
// If either type is a pointer, the other type has to be either an
140+
// integer or a pointer.
141+
if (!DestType->isArithmeticType()) {
142+
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
143+
index 85553eccde83..a40658da2b36 100644
144+
--- a/clang/lib/Sema/SemaExpr.cpp
145+
+++ b/clang/lib/Sema/SemaExpr.cpp
146+
@@ -10122,10 +10122,6 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
147+
const VectorType *RHSVecType = RHSType->getAs<VectorType>();
148+
assert(LHSVecType || RHSVecType);
149+
150+
- if ((LHSVecType && LHSVecType->getElementType()->isBFloat16Type()) ||
151+
- (RHSVecType && RHSVecType->getElementType()->isBFloat16Type()))
152+
- return InvalidOperands(Loc, LHS, RHS);
153+
-
154+
// AltiVec-style "vector bool op vector bool" combinations are allowed
155+
// for some operators but not others.
156+
if (!AllowBothBool &&
157+
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
158+
index 3fa192cedfa3..f232b0f4fcd0 100644
159+
--- a/clang/lib/Sema/SemaOverload.cpp
160+
+++ b/clang/lib/Sema/SemaOverload.cpp
161+
@@ -1873,8 +1873,11 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
162+
// if their representation is different until there is back end support
163+
// We of course allow this conversion if long double is really double.
164+
165+
- // Conversions between bfloat and other floats are not permitted.
166+
- if (FromType == S.Context.BFloat16Ty || ToType == S.Context.BFloat16Ty)
167+
+ // Conversions between bfloat16 and float16 are currently not supported.
168+
+ if ((FromType->isBFloat16Type() &&
169+
+ (ToType->isFloat16Type() || ToType->isHalfType())) ||
170+
+ (ToType->isBFloat16Type() &&
171+
+ (FromType->isFloat16Type() || FromType->isHalfType())))
172+
return false;
173+
174+
// Conversions between IEEE-quad and IBM-extended semantics are not
175+
@@ -1895,9 +1898,6 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
176+
ToType->isIntegralType(S.Context)) ||
177+
(FromType->isIntegralOrUnscopedEnumerationType() &&
178+
ToType->isRealFloatingType())) {
179+
- // Conversions between bfloat and int are not permitted.
180+
- if (FromType->isBFloat16Type() || ToType->isBFloat16Type())
181+
- return false;
182+
183+
// Floating-integral conversions (C++ 4.9).
184+
SCS.Second = ICK_Floating_Integral;
185+
--
186+
2.39.1
187+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
From a82f420c0f26413bb9d991a823e690f8f5475977 Mon Sep 17 00:00:00 2001
2+
From: Wenju He <[email protected]>
3+
Date: Fri, 21 Nov 2025 04:54:53 +0100
4+
Subject: [PATCH 2/2] [Clang] Enable BFloat16 for SPIR/SPIR-V
5+
6+
---
7+
clang/lib/Basic/Targets/SPIR.h | 3 +++
8+
1 file changed, 3 insertions(+)
9+
10+
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
11+
index a40d4b3ca27e..9541ad5b1af9 100644
12+
--- a/clang/lib/Basic/Targets/SPIR.h
13+
+++ b/clang/lib/Basic/Targets/SPIR.h
14+
@@ -92,6 +92,9 @@ protected:
15+
UseAddrSpaceMapMangling = true;
16+
HasLegalHalfType = true;
17+
HasFloat16 = true;
18+
+ HasBFloat16 = true;
19+
+ BFloat16Width = BFloat16Align = 16;
20+
+ BFloat16Format = &llvm::APFloat::BFloat();
21+
// Define available target features
22+
// These must be defined in sorted order!
23+
NoAsmVariants = true;
24+
--
25+
2.39.1
26+

0 commit comments

Comments
 (0)