-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[clang] Add __bf16
Type Support Macros With Literal Suffix Support
#134214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang Author: Muhammad Bassiouni (bassiounix) Changescloses #133660. I added the suffix support to this pr as the generated macros uses the The only line I found in GCC which we don't seem to support as a macro is #define __BFLT16_IS_IEC_60559__ 0 we don't have cc @AaronBallman @lntue @jhuber6 Full diff: https://github.com/llvm/llvm-project/pull/134214.diff 4 Files Affected:
diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h
index ea5f63bc20399..1907cfc365d97 100644
--- a/clang/include/clang/Lex/LiteralSupport.h
+++ b/clang/include/clang/Lex/LiteralSupport.h
@@ -77,6 +77,7 @@ class NumericLiteralParser {
bool isFloat : 1; // 1.0f
bool isImaginary : 1; // 1.0i
bool isFloat16 : 1; // 1.0f16
+ bool isBFloat16 : 1; // 1.0bf16
bool isFloat128 : 1; // 1.0q
bool isFract : 1; // 1.0hr/r/lr/uhr/ur/ulr
bool isAccum : 1; // 1.0hk/k/lk/uhk/uk/ulk
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 0b54665501c76..9bca74a8b4bd6 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -96,7 +96,7 @@ static void AddImplicitIncludePCH(MacroBuilder &Builder, Preprocessor &PP,
template <typename T>
static T PickFP(const llvm::fltSemantics *Sem, T IEEEHalfVal, T IEEESingleVal,
T IEEEDoubleVal, T X87DoubleExtendedVal, T PPCDoubleDoubleVal,
- T IEEEQuadVal) {
+ T BFloatVal, T IEEEQuadVal) {
if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEhalf())
return IEEEHalfVal;
if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEsingle())
@@ -107,6 +107,8 @@ static T PickFP(const llvm::fltSemantics *Sem, T IEEEHalfVal, T IEEESingleVal,
return X87DoubleExtendedVal;
if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::PPCDoubleDouble())
return PPCDoubleDoubleVal;
+ if (Sem == (const llvm::fltSemantics*)&llvm::APFloat::BFloat())
+ return BFloatVal;
assert(Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEquad());
return IEEEQuadVal;
}
@@ -117,29 +119,34 @@ static void DefineFloatMacros(MacroBuilder &Builder, StringRef Prefix,
NormMax = PickFP(Sem, "6.5504e+4", "3.40282347e+38",
"1.7976931348623157e+308", "1.18973149535723176502e+4932",
"8.98846567431157953864652595394501e+307",
+ "3.38953138925153547590470800371487867e+38",
"1.18973149535723176508575932662800702e+4932");
DenormMin = PickFP(Sem, "5.9604644775390625e-8", "1.40129846e-45",
"4.9406564584124654e-324", "3.64519953188247460253e-4951",
"4.94065645841246544176568792868221e-324",
+ "9.18354961579912115600575419704879436e-41",
"6.47517511943802511092443895822764655e-4966");
- int Digits = PickFP(Sem, 3, 6, 15, 18, 31, 33);
- int DecimalDigits = PickFP(Sem, 5, 9, 17, 21, 33, 36);
+ int Digits = PickFP(Sem, 3, 6, 15, 18, 31, 2, 33);
+ int DecimalDigits = PickFP(Sem, 5, 9, 17, 21, 33, 4, 36);
Epsilon = PickFP(Sem, "9.765625e-4", "1.19209290e-7",
"2.2204460492503131e-16", "1.08420217248550443401e-19",
"4.94065645841246544176568792868221e-324",
+ "7.81250000000000000000000000000000000e-3",
"1.92592994438723585305597794258492732e-34");
- int MantissaDigits = PickFP(Sem, 11, 24, 53, 64, 106, 113);
- int Min10Exp = PickFP(Sem, -4, -37, -307, -4931, -291, -4931);
- int Max10Exp = PickFP(Sem, 4, 38, 308, 4932, 308, 4932);
- int MinExp = PickFP(Sem, -13, -125, -1021, -16381, -968, -16381);
- int MaxExp = PickFP(Sem, 16, 128, 1024, 16384, 1024, 16384);
+ int MantissaDigits = PickFP(Sem, 11, 24, 53, 64, 106, 8, 113);
+ int Min10Exp = PickFP(Sem, -4, -37, -307, -4931, -291, -37, -4931);
+ int Max10Exp = PickFP(Sem, 4, 38, 308, 4932, 308, 38, 4932);
+ int MinExp = PickFP(Sem, -13, -125, -1021, -16381, -968, -125, -16381);
+ int MaxExp = PickFP(Sem, 16, 128, 1024, 16384, 1024, 128, 16384);
Min = PickFP(Sem, "6.103515625e-5", "1.17549435e-38", "2.2250738585072014e-308",
"3.36210314311209350626e-4932",
"2.00416836000897277799610805135016e-292",
+ "1.17549435082228750796873653722224568e-38",
"3.36210314311209350626267781732175260e-4932");
Max = PickFP(Sem, "6.5504e+4", "3.40282347e+38", "1.7976931348623157e+308",
"1.18973149535723176502e+4932",
"1.79769313486231580793728971405301e+308",
+ "3.38953138925153547590470800371487867e+38",
"1.18973149535723176508575932662800702e+4932");
SmallString<32> DefPrefix;
@@ -1250,6 +1257,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
if (TI.hasFloat16Type())
DefineFloatMacros(Builder, "FLT16", &TI.getHalfFormat(), "F16");
+ if (TI.hasBFloat16Type())
+ DefineFloatMacros(Builder, "BFLT16", &TI.getBFloat16Format(), "BF16");
DefineFloatMacros(Builder, "FLT", &TI.getFloatFormat(), "F");
DefineFloatMacros(Builder, "DBL", &TI.getDoubleFormat(), "");
DefineFloatMacros(Builder, "LDBL", &TI.getLongDoubleFormat(), "L");
diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp
index 20933cc8dee69..ab0d301a70fbd 100644
--- a/clang/lib/Lex/LiteralSupport.cpp
+++ b/clang/lib/Lex/LiteralSupport.cpp
@@ -917,6 +917,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
isFloat = false;
isImaginary = false;
isFloat16 = false;
+ isBFloat16 = false;
isFloat128 = false;
MicrosoftInteger = 0;
isFract = false;
@@ -973,11 +974,20 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
bool isFPConstant = isFloatingLiteral();
bool HasSize = false;
bool DoubleUnderscore = false;
+ bool isBF16 = false;
// Loop over all of the characters of the suffix. If we see something bad,
// we break out of the loop.
for (; s != ThisTokEnd; ++s) {
switch (*s) {
+ case 'b':
+ case 'B':
+ if (isBFloat16) break;
+ if (isBF16) break;
+ if (HasSize) break;
+
+ isBF16 = true;
+ continue;
case 'R':
case 'r':
if (!LangOpts.FixedPoint)
@@ -1022,7 +1032,11 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
(LangOpts.OpenMPIsTargetDevice && Target.getTriple().isNVPTX())) &&
s + 2 < ThisTokEnd && s[1] == '1' && s[2] == '6') {
s += 2; // success, eat up 2 characters.
- isFloat16 = true;
+ if (isBF16) {
+ isBFloat16 = true;
+ } else {
+ isFloat16 = true;
+ }
continue;
}
@@ -1183,6 +1197,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
isSizeT = false;
isFloat = false;
isFloat16 = false;
+ isBFloat16 = false;
isHalf = false;
isImaginary = false;
isBitInt = false;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3af6d6c23438f..b4210fc22ae52 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3878,6 +3878,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
Ty = !getLangOpts().HLSL ? Context.LongDoubleTy : Context.DoubleTy;
else if (Literal.isFloat16)
Ty = Context.Float16Ty;
+ else if (Literal.isBFloat16)
+ Ty = Context.BFloat16Ty;
else if (Literal.isFloat128)
Ty = Context.Float128Ty;
else if (getLangOpts().HLSL)
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
I changed the commits and ran test at each step, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this! It's heading in the right direction. Some things which are still missing are;
- a release note in
clang/docs/ReleaseNotes.rst
so users know about the new suffix and macros. - test coverage
clang/test/Lexer/
should get a test for the literal suffix supportclang/test/Preprocessor/
should get a test for the new predefined macros
As for the current test failures, they're both hitting the same failed assertion:
clang: /var/lib/buildkite-agent/builds/linux-56-59b8f5d88-bt7k7-1/llvm-project/github-pull-requests/clang/lib/Frontend/InitPreprocessor.cpp:112: T PickFP(const llvm::fltSemantics *, T, T, T, T, T, T, T) [T = const char *]: Assertion `Sem == (const llvm::fltSemantics*)&llvm::APFloat::IEEEquad()' failed.
It almost seems as though &TI.getBFloat16Format()
is returning something other than &llvm::APFloat::BFloat()
for a target and thus it falls into the quad assertion while not being a quad semantics. You'll likely have to hook up a debugger to see what's going on there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR currently adds two suffixes: bf16
and just b
. Is this intended? GCC seems to only support bf16
: https://godbolt.org/z/hEfcrGrG1.
It currently also lets Clang accept the following C++ code if the target doesn't have bfloat16 but has float16:
auto foo = 1.0bf16;
And it lets Clang accept the following C++ code even if the target has neither bfloat16 nor float16:
auto foo = 1.0b;
It also looks like foo
ends up being of type double
either way (edit: nevermind, it was only happening with 1.0b
, because it was only setting the isBF16
local variable and not isBFloat16
):
TranslationUnitDecl 0x5f0373f42d48 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x5f0373f439d0 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
| `-BuiltinType 0x5f0373f43310 '__int128'
|-TypedefDecl 0x5f0373f43a40 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
| `-BuiltinType 0x5f0373f43330 'unsigned __int128'
|-TypedefDecl 0x5f0373f91f70 <<invalid sloc>> <invalid sloc> implicit __NSConstantString '__NSConstantString_tag'
| `-RecordType 0x5f0373f43b30 '__NSConstantString_tag'
| `-CXXRecord 0x5f0373f43a98 '__NSConstantString_tag'
|-TypedefDecl 0x5f0373f43608 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'
| `-PointerType 0x5f0373f435c0 'char *'
| `-BuiltinType 0x5f0373f42df0 'char'
|-TypedefDecl 0x5f0373f43960 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list '__va_list_tag[1]'
| `-ConstantArrayType 0x5f0373f43910 '__va_list_tag[1]' 1
| `-RecordType 0x5f0373f436f0 '__va_list_tag'
| `-CXXRecord 0x5f0373f43660 '__va_list_tag'
`-VarDecl 0x5f0373f92018 <a.cpp:1:1, col:12> col:6 foo 'double' cinit
`-FloatingLiteral 0x5f0373f920c8 <col:12> 'double' 1.000000e+00
Looks like that The global value of I think Edit: was just a "copy" problem |
Co-authored-by: OverMighty <[email protected]>
Co-authored-by: OverMighty <[email protected]>
Co-authored-by: OverMighty <[email protected]>
case 'b': // FP Suffix for "__bf16" | ||
case 'B': | ||
if (!Target.hasBFloat16Type()) | ||
break; | ||
if (!isFPConstant) | ||
break; // Error for integer constant. | ||
if (HasSize) | ||
break; | ||
HasSize = true; | ||
|
||
if (s + 3 < ThisTokEnd && | ||
((s[0] == 'b' && s[1] == 'f') || (s[0] == 'B' && s[1] == 'F')) && | ||
s[2] == '1' && s[3] == '6') { | ||
s += 3; // success, eat up 3 characters. | ||
isBFloat16 = true; | ||
continue; | ||
} | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is true for C++23. Do we want extension warnings in other language modes @AaronBallman?
As an aside, did anyone benchmark that the pattern we use in this function is actually faster than string_view
comparisons?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we should have extension warnings in other language modes as well as the precompat warning for C++ before C++23.
closes #133660.
I added the suffix support to this pr as the generated macros uses the
BF16
suffix.The only line I found in GCC which we don't seem to support as a macro is
we don't have
__*_IS_IEC_60559__
in our macro builder so I skipped it.cc @AaronBallman @lntue @jhuber6