-
Notifications
You must be signed in to change notification settings - Fork 12.3k
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
[CLANG][AArch64] Add the modal 8 bit floating-point scalar type #97277
Conversation
@llvm/pr-subscribers-debuginfo @llvm/pr-subscribers-clang-codegen Author: None (CarolineConcatto) ChangesARM ACLE PR#323[1] adds new modal types for 8-bit floating point intrinsic. From the PR#323:
The type should be an opaque type and its format in undefined in Clang. Only defined in the backend by a status/format register, for AArch64 the FPMR. This patch is an attempt to the add the fpm8_t scalar type. It has a parser and codegen for the new scalar type. The patch it is lowering to and 8bit unsigned as it has no format. But maybe we should add another opaque type. Full diff: https://github.com/llvm/llvm-project/pull/97277.diff 25 Files Affected:
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 53ece996769a8..532ec05ab90a6 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1115,6 +1115,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
CanQualType SatShortFractTy, SatFractTy, SatLongFractTy;
CanQualType SatUnsignedShortFractTy, SatUnsignedFractTy,
SatUnsignedLongFractTy;
+ CanQualType Fpm8Ty;
CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
CanQualType BFloat16Ty;
CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def
index 444be4311a743..0c1cccf4f73b8 100644
--- a/clang/include/clang/AST/BuiltinTypes.def
+++ b/clang/include/clang/AST/BuiltinTypes.def
@@ -221,6 +221,10 @@ FLOATING_TYPE(Float128, Float128Ty)
// '__ibm128'
FLOATING_TYPE(Ibm128, Ibm128Ty)
+
+// '__fpm8'
+UNSIGNED_TYPE(Fpm8, Fpm8Ty)
+
//===- Language-specific types --------------------------------------------===//
// This is the type of C++0x 'nullptr'.
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index fab233b62d8d1..9f835b8459847 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2492,6 +2492,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
bool isDoubleType() const;
bool isBFloat16Type() const;
bool isFloat128Type() const;
+ bool isFpm8Type() const;
bool isIbm128Type() const;
bool isRealType() const; // C99 6.2.5p17 (real floating + integer)
bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating)
@@ -7944,6 +7945,10 @@ inline bool Type::isBFloat16Type() const {
return isSpecificBuiltinType(BuiltinType::BFloat16);
}
+inline bool Type::isFpm8Type() const {
+ return isSpecificBuiltinType(BuiltinType::Fpm8);
+}
+
inline bool Type::isFloat128Type() const {
return isSpecificBuiltinType(BuiltinType::Float128);
}
diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h
index fb11e8212f8b6..b4db94d273949 100644
--- a/clang/include/clang/Basic/Specifiers.h
+++ b/clang/include/clang/Basic/Specifiers.h
@@ -68,6 +68,7 @@ namespace clang {
TST_Accum, // ISO/IEC JTC1 SC22 WG14 N1169 Extension
TST_Fract,
TST_BFloat16,
+ TST_Fpm8,
TST_float,
TST_double,
TST_float128,
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 9c4b17465e18a..c08cf760962f3 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -655,6 +655,7 @@ KEYWORD(__bool , KEYALTIVEC|KEYZVECTOR)
// ARM NEON extensions.
ALIAS("__fp16", half , KEYALL)
KEYWORD(__bf16 , KEYALL)
+KEYWORD(__fpm8 , KEYALL)
// OpenCL Extension.
KEYWORD(half , HALFSUPPORT)
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 23bc780e04979..097cb8eb642ac 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -287,6 +287,7 @@ class DeclSpec {
static const TST TST_bitint = clang::TST_bitint;
static const TST TST_half = clang::TST_half;
static const TST TST_BFloat16 = clang::TST_BFloat16;
+ static const TST TST_Fpm8 = clang::TST_Fpm8;
static const TST TST_float = clang::TST_float;
static const TST TST_double = clang::TST_double;
static const TST TST_float16 = clang::TST_Float16;
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index a4728b1c06b3f..b2853c5e787d6 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1078,6 +1078,8 @@ enum PredefinedTypeIDs {
/// \brief The '__ibm128' type
PREDEF_TYPE_IBM128_ID = 74,
+ PREDEF_TYPE_FPM8_ID = 75,
+
/// OpenCL image types with auto numeration
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
PREDEF_TYPE_##Id##_ID,
@@ -1109,7 +1111,7 @@ enum PredefinedTypeIDs {
///
/// Type IDs for non-predefined types will start at
/// NUM_PREDEF_TYPE_IDs.
-const unsigned NUM_PREDEF_TYPE_IDS = 503;
+const unsigned NUM_PREDEF_TYPE_IDS = 504;
// Ensure we do not overrun the predefined types we reserved
// in the enum PredefinedTypeIDs above.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 34aa399fda2f8..7d810c1f8751e 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1408,6 +1408,8 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
// half type (OpenCL 6.1.1.1) / ARM NEON __fp16
InitBuiltinType(HalfTy, BuiltinType::Half);
+ InitBuiltinType(Fpm8Ty, BuiltinType::Fpm8);
+
InitBuiltinType(BFloat16Ty, BuiltinType::BFloat16);
// Builtin type used to help define __builtin_va_list.
@@ -1977,6 +1979,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = Target->getBoolWidth();
Align = Target->getBoolAlign();
break;
+ case BuiltinType::Fpm8:
case BuiltinType::Char_S:
case BuiltinType::Char_U:
case BuiltinType::UChar:
@@ -8129,6 +8132,7 @@ static char getObjCEncodingForPrimitiveType(const ASTContext *C,
case BuiltinType::LongDouble: return 'D';
case BuiltinType::NullPtr: return '*'; // like char*
+ case BuiltinType::Fpm8:
case BuiltinType::BFloat16:
case BuiltinType::Float16:
case BuiltinType::Float128:
@@ -11466,6 +11470,9 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
else
Type = Context.CharTy;
break;
+ case '£':
+ Type = Context.Fpm8Ty;
+ break;
case 'b': // boolean
assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'b'!");
Type = Context.BoolTy;
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index ed9e6eeb36c75..f974cf1b5f8a8 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3181,6 +3181,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
case BuiltinType::SChar:
Out << 'a';
break;
+ case BuiltinType::Fpm8:
case BuiltinType::WChar_S:
case BuiltinType::WChar_U:
Out << 'w';
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 33acae2cbafac..f629ae6d7b016 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -3372,6 +3372,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
return "unsigned __int128";
case Half:
return Policy.Half ? "half" : "__fp16";
+ case Fpm8:
+ return "__fpm8";
case BFloat16:
return "__bf16";
case Float:
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index 9dd90d9bf4e54..8df92d3921c44 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -361,6 +361,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
case BuiltinType::Long:
case BuiltinType::LongLong:
case BuiltinType::Int128:
+ case BuiltinType::Fpm8:
case BuiltinType::Half:
case BuiltinType::Float:
case BuiltinType::Double:
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index 0a926e4ac27fe..626525f66e3e7 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -419,7 +419,9 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
Context.getFloatTypeSemantics(T),
/* UseNativeHalf = */ false);
break;
-
+ case BuiltinType::Fpm8:
+ ResultType = llvm::Type::getInt8Ty(getLLVMContext());
+ break;
case BuiltinType::NullPtr:
// Model std::nullptr_t as i8*
ResultType = llvm::PointerType::getUnqual(getLLVMContext());
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 5a3e83de625c9..8ae3c1c38b3e5 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3331,6 +3331,7 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
case BuiltinType::Float:
case BuiltinType::Double:
case BuiltinType::LongDouble:
+ case BuiltinType::Fpm8:
case BuiltinType::Float16:
case BuiltinType::Float128:
case BuiltinType::Ibm128:
diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp
index 31c4a3345c09d..553b788ee0e75 100644
--- a/clang/lib/Index/USRGeneration.cpp
+++ b/clang/lib/Index/USRGeneration.cpp
@@ -691,6 +691,7 @@ void USRGenerator::VisitType(QualType T) {
Out << 'v'; break;
case BuiltinType::Bool:
Out << 'b'; break;
+ case BuiltinType::Fpm8:
case BuiltinType::UChar:
Out << 'c'; break;
case BuiltinType::Char8:
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index e59c7805b3862..7806ea9d8604f 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -97,6 +97,7 @@ bool Token::isSimpleTypeSpecifier(const LangOptions &LangOpts) const {
case tok::kw___bf16:
case tok::kw__Float16:
case tok::kw___float128:
+ case tok::kw___fpm8:
case tok::kw___ibm128:
case tok::kw_wchar_t:
case tok::kw_bool:
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index c528917437332..25838d65f3e51 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4477,6 +4477,10 @@ void Parser::ParseDeclarationSpecifiers(
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,
DiagID, Policy);
break;
+ case tok::kw___fpm8:
+ isInvalid =
+ DS.SetTypeSpecType(DeclSpec::TST_Fpm8, Loc, PrevSpec, DiagID, Policy);
+ break;
case tok::kw_half:
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
DiagID, Policy);
@@ -5752,6 +5756,7 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
case tok::kw__ExtInt:
case tok::kw__BitInt:
case tok::kw___bf16:
+ case tok::kw___fpm8:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
@@ -5835,6 +5840,7 @@ bool Parser::isTypeSpecifierQualifier() {
case tok::kw_int:
case tok::kw__ExtInt:
case tok::kw__BitInt:
+ case tok::kw___fpm8:
case tok::kw_half:
case tok::kw___bf16:
case tok::kw_float:
@@ -6057,6 +6063,7 @@ bool Parser::isDeclarationSpecifier(
case tok::kw_int:
case tok::kw__ExtInt:
case tok::kw__BitInt:
+ case tok::kw___fpm8:
case tok::kw_half:
case tok::kw___bf16:
case tok::kw_float:
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index eb7447fa038e4..9103275aa9772 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1594,6 +1594,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
case tok::kw__BitInt:
case tok::kw_signed:
case tok::kw_unsigned:
+ case tok::kw___fpm8:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 1d364f77a8146..72c4782cb53b3 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -2405,6 +2405,9 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
case tok::kw___int128:
DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID, Policy);
break;
+ case tok::kw___fpm8:
+ DS.SetTypeSpecType(DeclSpec::TST_Fpm8, Loc, PrevSpec, DiagID, Policy);
+ break;
case tok::kw___bf16:
DS.SetTypeSpecType(DeclSpec::TST_BFloat16, Loc, PrevSpec, DiagID, Policy);
break;
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index ea17c3e3252ec..695bbbba9433d 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -1779,6 +1779,7 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
case tok::kw_short:
case tok::kw_int:
case tok::kw_long:
+ case tok::kw___fpm8:
case tok::kw___int64:
case tok::kw___int128:
case tok::kw_signed:
@@ -1907,6 +1908,7 @@ bool Parser::isCXXDeclarationSpecifierAType() {
case tok::kw_long:
case tok::kw___int64:
case tok::kw___int128:
+ case tok::kw___fpm8:
case tok::kw_signed:
case tok::kw_unsigned:
case tok::kw_half:
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index 60e8189025700..168b98e90e6ec 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -358,6 +358,7 @@ bool Declarator::isDeclarationOfFunction() const {
case TST_Fract:
case TST_Float16:
case TST_float128:
+ case TST_Fpm8:
case TST_ibm128:
case TST_enum:
case TST_error:
@@ -575,6 +576,8 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
case DeclSpec::TST_fract: return "_Fract";
case DeclSpec::TST_float16: return "_Float16";
case DeclSpec::TST_float128: return "__float128";
+ case DeclSpec::TST_Fpm8:
+ return "fpm8_t";
case DeclSpec::TST_ibm128: return "__ibm128";
case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool";
case DeclSpec::TST_decimal32: return "_Decimal32";
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 7a44b978aacdb..d7c4c04c130ef 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -908,6 +908,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
case TST_char32:
case TST_int:
case TST_int128:
+ case TST_Fpm8:
case TST_half:
case TST_float:
case TST_double:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 441fdcca0758f..89c523990ce52 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -1134,6 +1134,9 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) << "__bf16";
Result = Context.BFloat16Ty;
break;
+ case DeclSpec::TST_Fpm8:
+ Result = Context.Fpm8Ty;
+ break;
case DeclSpec::TST_float: Result = Context.FloatTy; break;
case DeclSpec::TST_double:
if (DS.getTypeSpecWidth() == TypeSpecifierWidth::Long)
diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp
index bc662a87a7bf3..a01d57cc1fcab 100644
--- a/clang/lib/Serialization/ASTCommon.cpp
+++ b/clang/lib/Serialization/ASTCommon.cpp
@@ -35,6 +35,9 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
case BuiltinType::Char_U:
ID = PREDEF_TYPE_CHAR_U_ID;
break;
+ case BuiltinType::Fpm8:
+ ID = PREDEF_TYPE_FPM8_ID;
+ break;
case BuiltinType::UChar:
ID = PREDEF_TYPE_UCHAR_ID;
break;
diff --git a/clang/test/AST/fpm8_opaque.cpp b/clang/test/AST/fpm8_opaque.cpp
new file mode 100644
index 0000000000000..3aeb3159ddc6a
--- /dev/null
+++ b/clang/test/AST/fpm8_opaque.cpp
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace
+
+/* Various contexts where type __fpm8 can appear. */
+
+/* Namespace */
+namespace {
+ __fpm8 f2n;
+ __fpm8 arr1n[10];
+}
+
+//CHECK: |-NamespaceDecl {{.*}}
+//CHECK-NEXT: | |-VarDecl {{.*}} f2n '__fpm8'
+//CHECK-NEXT: | `-VarDecl {{.*}} arr1n '__fpm8[10]'
+
+ __fpm8 arr1[10];
+ //__fpm8 arr2n[] { 1, 3, 3 }; cannot initialize
+
+ const __fpm8 func1n(const __fpm8 fpm8) {
+ // this should fail
+ __fpm8 f1n;
+ f1n = fpm8;
+ return f1n;
+ }
+
+//CHECK: |-VarDecl {{.*}} '__fpm8[10]'
+
+//CHECK: | `-VarDecl {{.*}} f1n '__fpm8'
+//CHECK-NEXT: |-BinaryOperator {{.*}} '__fpm8' lvalue '='
+//CHECK-NEXT: | |-DeclRefExpr {{.*}} '__fpm8' lvalue Var {{.*}} 'f1n' '__fpm8'
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue>
+//CHECK-NEXT: | `-DeclRefExpr {{.*}} 'const __fpm8' lvalue ParmVar {{.*}} 'fpm8' 'const __fpm8'
+//CHECK-NEXT: `-ReturnStmt {{.*}}
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue>
+//CHECK-NEXT: `-DeclRefExpr {{.*}} '__fpm8' lvalue Var {{.*}} 'f1n' '__fpm8'
+
+
+/* Class */
+
+class C1 {
+ __fpm8 f1c;
+ static const __fpm8 f2c;
+ volatile __fpm8 f3c;
+public:
+ C1(__fpm8 arg) : f1c(arg), f3c(arg) { }
+ __fpm8 func1c(__fpm8 arg ) {
+ return arg;
+ }
+ static __fpm8 func2c(__fpm8 arg) {
+ return arg;
+ }
+};
+
+//CHECK: | |-CXXRecordDecl {{.*}} referenced class C1
+//CHECK-NEXT: | |-FieldDecl {{.*}} f1c '__fpm8'
+//CHECK-NEXT: | |-VarDecl {{.*}} f2c 'const __fpm8' static
+//CHECK-NEXT: | |-FieldDecl {{.*}} f3c 'volatile __fpm8'
+//CHECK-NEXT: | |-AccessSpecDecl {{.*}}
+//CHECK-NEXT: | |-CXXConstructorDecl {{.*}} C1 'void (__fpm8)' implicit-inline
+//CHECK-NEXT: | | |-ParmVarDecl {{.*}} arg '__fpm8'
+//CHECK-NEXT: | | |-CXXCtorInitializer {{.*}} 'f1c' '__fpm8'
+//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue>
+//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '__fpm8' lvalue ParmVar {{.*}} 'arg' '__fpm8'
+//CHECK-NEXT: | | |-CXXCtorInitializer {{.*}} 'f3c' 'volatile __fpm8'
+//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue>
+//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '__fpm8' lvalue ParmVar {{.*}} 'arg' '__fpm8'
+//CHECK-NEXT: | | `-CompoundStmt {{.*}}
+//CHECK-NEXT: | |-CXXMethodDecl {{.*}} func1c '__fpm8 (__fpm8)' implicit-inline
+//CHECK-NEXT: | | |-ParmVarDecl {{.*}} arg '__fpm8'
+//CHECK-NEXT: | | `-CompoundStmt {{.*}}
+//CHECK-NEXT: | | `-ReturnStmt {{.*}}
+//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue>
+//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '__fpm8' lvalue ParmVar {{.*}}8 'arg' '__fpm8'
+//CHECK-NEXT: | `-CXXMethodDecl {{.*}} func2c '__fpm8 (__fpm8)' static implicit-inline
+//CHECK-NEXT: | |-ParmVarDecl {{.*}} arg '__fpm8'
+//CHECK-NEXT: | `-CompoundStmt {{.*}}
+//CHECK-NEXT: | `-ReturnStmt {{.*}}
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue>
+//CHECK-NEXT: | `-DeclRefExpr {{.*}} '__fpm8' lvalue ParmVar {{.*}} 'arg' '__fpm8'
+
+template <class C> struct S1 {
+ C mem1;
+};
+
+template <> struct S1<__fpm8> {
+ __fpm8 mem2;
+};
+
+//CHECK: |-TemplateArgument type '__fpm8'
+//CHECK-NEXT: | `-BuiltinType {{.*}} '__fpm8'
+//CHECK-NEXT: |-CXXRecordDecl {{.*}} implicit struct S1
+//CHECK-NEXT: `-FieldDecl {{.*}} mem2 '__fpm8'
diff --git a/clang/test/CodeGen/fpm8_opaque.c b/clang/test/CodeGen/fpm8_opaque.c
new file mode 100644
index 0000000000000..19b5128b8eff9
--- /dev/null
+++ b/clang/test/CodeGen/fpm8_opaque.c
@@ -0,0 +1,24 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define dso_local i8 @func1n(
+// CHECK-SAME: i8 noundef [[FPM8:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[FPM8_ADDR:%.*]] = alloca i8, align 1
+// CHECK-NEXT: [[F1N:%.*]] = alloca [10 x i8], align 1
+// CHECK-NEXT: store i8 [[FPM8]], ptr [[FPM8_ADDR]], align 1
+// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[FPM8_ADDR]], align 1
+// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i8], ptr [[F1N]], i64 0, i64 2
+// CHECK-NEXT: store i8 [[TMP0]], ptr [[ARRAYIDX]], align 1
+// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [10 x i8], ptr [[F1N]], i64 0, i64 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
+// CHECK-NEXT: ret i8 [[TMP1]]
+//
+__fpm8 func1n(__fpm8 fpm8) {
+ __fpm8 f1n[10];
+ f1n[2] = fpm8;
+ return f1n[2];
+}
+
+
+
|
@llvm/pr-subscribers-clang Author: None (CarolineConcatto) ChangesARM ACLE PR#323[1] adds new modal types for 8-bit floating point intrinsic. From the PR#323:
The type should be an opaque type and its format in undefined in Clang. Only defined in the backend by a status/format register, for AArch64 the FPMR. This patch is an attempt to the add the fpm8_t scalar type. It has a parser and codegen for the new scalar type. The patch it is lowering to and 8bit unsigned as it has no format. But maybe we should add another opaque type. Full diff: https://github.com/llvm/llvm-project/pull/97277.diff 25 Files Affected:
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 53ece996769a8..532ec05ab90a6 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1115,6 +1115,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
CanQualType SatShortFractTy, SatFractTy, SatLongFractTy;
CanQualType SatUnsignedShortFractTy, SatUnsignedFractTy,
SatUnsignedLongFractTy;
+ CanQualType Fpm8Ty;
CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
CanQualType BFloat16Ty;
CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def
index 444be4311a743..0c1cccf4f73b8 100644
--- a/clang/include/clang/AST/BuiltinTypes.def
+++ b/clang/include/clang/AST/BuiltinTypes.def
@@ -221,6 +221,10 @@ FLOATING_TYPE(Float128, Float128Ty)
// '__ibm128'
FLOATING_TYPE(Ibm128, Ibm128Ty)
+
+// '__fpm8'
+UNSIGNED_TYPE(Fpm8, Fpm8Ty)
+
//===- Language-specific types --------------------------------------------===//
// This is the type of C++0x 'nullptr'.
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index fab233b62d8d1..9f835b8459847 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2492,6 +2492,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
bool isDoubleType() const;
bool isBFloat16Type() const;
bool isFloat128Type() const;
+ bool isFpm8Type() const;
bool isIbm128Type() const;
bool isRealType() const; // C99 6.2.5p17 (real floating + integer)
bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating)
@@ -7944,6 +7945,10 @@ inline bool Type::isBFloat16Type() const {
return isSpecificBuiltinType(BuiltinType::BFloat16);
}
+inline bool Type::isFpm8Type() const {
+ return isSpecificBuiltinType(BuiltinType::Fpm8);
+}
+
inline bool Type::isFloat128Type() const {
return isSpecificBuiltinType(BuiltinType::Float128);
}
diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h
index fb11e8212f8b6..b4db94d273949 100644
--- a/clang/include/clang/Basic/Specifiers.h
+++ b/clang/include/clang/Basic/Specifiers.h
@@ -68,6 +68,7 @@ namespace clang {
TST_Accum, // ISO/IEC JTC1 SC22 WG14 N1169 Extension
TST_Fract,
TST_BFloat16,
+ TST_Fpm8,
TST_float,
TST_double,
TST_float128,
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 9c4b17465e18a..c08cf760962f3 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -655,6 +655,7 @@ KEYWORD(__bool , KEYALTIVEC|KEYZVECTOR)
// ARM NEON extensions.
ALIAS("__fp16", half , KEYALL)
KEYWORD(__bf16 , KEYALL)
+KEYWORD(__fpm8 , KEYALL)
// OpenCL Extension.
KEYWORD(half , HALFSUPPORT)
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 23bc780e04979..097cb8eb642ac 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -287,6 +287,7 @@ class DeclSpec {
static const TST TST_bitint = clang::TST_bitint;
static const TST TST_half = clang::TST_half;
static const TST TST_BFloat16 = clang::TST_BFloat16;
+ static const TST TST_Fpm8 = clang::TST_Fpm8;
static const TST TST_float = clang::TST_float;
static const TST TST_double = clang::TST_double;
static const TST TST_float16 = clang::TST_Float16;
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index a4728b1c06b3f..b2853c5e787d6 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1078,6 +1078,8 @@ enum PredefinedTypeIDs {
/// \brief The '__ibm128' type
PREDEF_TYPE_IBM128_ID = 74,
+ PREDEF_TYPE_FPM8_ID = 75,
+
/// OpenCL image types with auto numeration
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
PREDEF_TYPE_##Id##_ID,
@@ -1109,7 +1111,7 @@ enum PredefinedTypeIDs {
///
/// Type IDs for non-predefined types will start at
/// NUM_PREDEF_TYPE_IDs.
-const unsigned NUM_PREDEF_TYPE_IDS = 503;
+const unsigned NUM_PREDEF_TYPE_IDS = 504;
// Ensure we do not overrun the predefined types we reserved
// in the enum PredefinedTypeIDs above.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 34aa399fda2f8..7d810c1f8751e 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1408,6 +1408,8 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
// half type (OpenCL 6.1.1.1) / ARM NEON __fp16
InitBuiltinType(HalfTy, BuiltinType::Half);
+ InitBuiltinType(Fpm8Ty, BuiltinType::Fpm8);
+
InitBuiltinType(BFloat16Ty, BuiltinType::BFloat16);
// Builtin type used to help define __builtin_va_list.
@@ -1977,6 +1979,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = Target->getBoolWidth();
Align = Target->getBoolAlign();
break;
+ case BuiltinType::Fpm8:
case BuiltinType::Char_S:
case BuiltinType::Char_U:
case BuiltinType::UChar:
@@ -8129,6 +8132,7 @@ static char getObjCEncodingForPrimitiveType(const ASTContext *C,
case BuiltinType::LongDouble: return 'D';
case BuiltinType::NullPtr: return '*'; // like char*
+ case BuiltinType::Fpm8:
case BuiltinType::BFloat16:
case BuiltinType::Float16:
case BuiltinType::Float128:
@@ -11466,6 +11470,9 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
else
Type = Context.CharTy;
break;
+ case '£':
+ Type = Context.Fpm8Ty;
+ break;
case 'b': // boolean
assert(HowLong == 0 && !Signed && !Unsigned && "Bad modifiers for 'b'!");
Type = Context.BoolTy;
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index ed9e6eeb36c75..f974cf1b5f8a8 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3181,6 +3181,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
case BuiltinType::SChar:
Out << 'a';
break;
+ case BuiltinType::Fpm8:
case BuiltinType::WChar_S:
case BuiltinType::WChar_U:
Out << 'w';
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 33acae2cbafac..f629ae6d7b016 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -3372,6 +3372,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
return "unsigned __int128";
case Half:
return Policy.Half ? "half" : "__fp16";
+ case Fpm8:
+ return "__fpm8";
case BFloat16:
return "__bf16";
case Float:
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index 9dd90d9bf4e54..8df92d3921c44 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -361,6 +361,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
case BuiltinType::Long:
case BuiltinType::LongLong:
case BuiltinType::Int128:
+ case BuiltinType::Fpm8:
case BuiltinType::Half:
case BuiltinType::Float:
case BuiltinType::Double:
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index 0a926e4ac27fe..626525f66e3e7 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -419,7 +419,9 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
Context.getFloatTypeSemantics(T),
/* UseNativeHalf = */ false);
break;
-
+ case BuiltinType::Fpm8:
+ ResultType = llvm::Type::getInt8Ty(getLLVMContext());
+ break;
case BuiltinType::NullPtr:
// Model std::nullptr_t as i8*
ResultType = llvm::PointerType::getUnqual(getLLVMContext());
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 5a3e83de625c9..8ae3c1c38b3e5 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3331,6 +3331,7 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
case BuiltinType::Float:
case BuiltinType::Double:
case BuiltinType::LongDouble:
+ case BuiltinType::Fpm8:
case BuiltinType::Float16:
case BuiltinType::Float128:
case BuiltinType::Ibm128:
diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp
index 31c4a3345c09d..553b788ee0e75 100644
--- a/clang/lib/Index/USRGeneration.cpp
+++ b/clang/lib/Index/USRGeneration.cpp
@@ -691,6 +691,7 @@ void USRGenerator::VisitType(QualType T) {
Out << 'v'; break;
case BuiltinType::Bool:
Out << 'b'; break;
+ case BuiltinType::Fpm8:
case BuiltinType::UChar:
Out << 'c'; break;
case BuiltinType::Char8:
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index e59c7805b3862..7806ea9d8604f 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -97,6 +97,7 @@ bool Token::isSimpleTypeSpecifier(const LangOptions &LangOpts) const {
case tok::kw___bf16:
case tok::kw__Float16:
case tok::kw___float128:
+ case tok::kw___fpm8:
case tok::kw___ibm128:
case tok::kw_wchar_t:
case tok::kw_bool:
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index c528917437332..25838d65f3e51 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4477,6 +4477,10 @@ void Parser::ParseDeclarationSpecifiers(
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,
DiagID, Policy);
break;
+ case tok::kw___fpm8:
+ isInvalid =
+ DS.SetTypeSpecType(DeclSpec::TST_Fpm8, Loc, PrevSpec, DiagID, Policy);
+ break;
case tok::kw_half:
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
DiagID, Policy);
@@ -5752,6 +5756,7 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
case tok::kw__ExtInt:
case tok::kw__BitInt:
case tok::kw___bf16:
+ case tok::kw___fpm8:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
@@ -5835,6 +5840,7 @@ bool Parser::isTypeSpecifierQualifier() {
case tok::kw_int:
case tok::kw__ExtInt:
case tok::kw__BitInt:
+ case tok::kw___fpm8:
case tok::kw_half:
case tok::kw___bf16:
case tok::kw_float:
@@ -6057,6 +6063,7 @@ bool Parser::isDeclarationSpecifier(
case tok::kw_int:
case tok::kw__ExtInt:
case tok::kw__BitInt:
+ case tok::kw___fpm8:
case tok::kw_half:
case tok::kw___bf16:
case tok::kw_float:
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index eb7447fa038e4..9103275aa9772 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1594,6 +1594,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
case tok::kw__BitInt:
case tok::kw_signed:
case tok::kw_unsigned:
+ case tok::kw___fpm8:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 1d364f77a8146..72c4782cb53b3 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -2405,6 +2405,9 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
case tok::kw___int128:
DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID, Policy);
break;
+ case tok::kw___fpm8:
+ DS.SetTypeSpecType(DeclSpec::TST_Fpm8, Loc, PrevSpec, DiagID, Policy);
+ break;
case tok::kw___bf16:
DS.SetTypeSpecType(DeclSpec::TST_BFloat16, Loc, PrevSpec, DiagID, Policy);
break;
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index ea17c3e3252ec..695bbbba9433d 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -1779,6 +1779,7 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
case tok::kw_short:
case tok::kw_int:
case tok::kw_long:
+ case tok::kw___fpm8:
case tok::kw___int64:
case tok::kw___int128:
case tok::kw_signed:
@@ -1907,6 +1908,7 @@ bool Parser::isCXXDeclarationSpecifierAType() {
case tok::kw_long:
case tok::kw___int64:
case tok::kw___int128:
+ case tok::kw___fpm8:
case tok::kw_signed:
case tok::kw_unsigned:
case tok::kw_half:
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index 60e8189025700..168b98e90e6ec 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -358,6 +358,7 @@ bool Declarator::isDeclarationOfFunction() const {
case TST_Fract:
case TST_Float16:
case TST_float128:
+ case TST_Fpm8:
case TST_ibm128:
case TST_enum:
case TST_error:
@@ -575,6 +576,8 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
case DeclSpec::TST_fract: return "_Fract";
case DeclSpec::TST_float16: return "_Float16";
case DeclSpec::TST_float128: return "__float128";
+ case DeclSpec::TST_Fpm8:
+ return "fpm8_t";
case DeclSpec::TST_ibm128: return "__ibm128";
case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool";
case DeclSpec::TST_decimal32: return "_Decimal32";
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 7a44b978aacdb..d7c4c04c130ef 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -908,6 +908,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
case TST_char32:
case TST_int:
case TST_int128:
+ case TST_Fpm8:
case TST_half:
case TST_float:
case TST_double:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 441fdcca0758f..89c523990ce52 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -1134,6 +1134,9 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) << "__bf16";
Result = Context.BFloat16Ty;
break;
+ case DeclSpec::TST_Fpm8:
+ Result = Context.Fpm8Ty;
+ break;
case DeclSpec::TST_float: Result = Context.FloatTy; break;
case DeclSpec::TST_double:
if (DS.getTypeSpecWidth() == TypeSpecifierWidth::Long)
diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp
index bc662a87a7bf3..a01d57cc1fcab 100644
--- a/clang/lib/Serialization/ASTCommon.cpp
+++ b/clang/lib/Serialization/ASTCommon.cpp
@@ -35,6 +35,9 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
case BuiltinType::Char_U:
ID = PREDEF_TYPE_CHAR_U_ID;
break;
+ case BuiltinType::Fpm8:
+ ID = PREDEF_TYPE_FPM8_ID;
+ break;
case BuiltinType::UChar:
ID = PREDEF_TYPE_UCHAR_ID;
break;
diff --git a/clang/test/AST/fpm8_opaque.cpp b/clang/test/AST/fpm8_opaque.cpp
new file mode 100644
index 0000000000000..3aeb3159ddc6a
--- /dev/null
+++ b/clang/test/AST/fpm8_opaque.cpp
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace
+
+/* Various contexts where type __fpm8 can appear. */
+
+/* Namespace */
+namespace {
+ __fpm8 f2n;
+ __fpm8 arr1n[10];
+}
+
+//CHECK: |-NamespaceDecl {{.*}}
+//CHECK-NEXT: | |-VarDecl {{.*}} f2n '__fpm8'
+//CHECK-NEXT: | `-VarDecl {{.*}} arr1n '__fpm8[10]'
+
+ __fpm8 arr1[10];
+ //__fpm8 arr2n[] { 1, 3, 3 }; cannot initialize
+
+ const __fpm8 func1n(const __fpm8 fpm8) {
+ // this should fail
+ __fpm8 f1n;
+ f1n = fpm8;
+ return f1n;
+ }
+
+//CHECK: |-VarDecl {{.*}} '__fpm8[10]'
+
+//CHECK: | `-VarDecl {{.*}} f1n '__fpm8'
+//CHECK-NEXT: |-BinaryOperator {{.*}} '__fpm8' lvalue '='
+//CHECK-NEXT: | |-DeclRefExpr {{.*}} '__fpm8' lvalue Var {{.*}} 'f1n' '__fpm8'
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue>
+//CHECK-NEXT: | `-DeclRefExpr {{.*}} 'const __fpm8' lvalue ParmVar {{.*}} 'fpm8' 'const __fpm8'
+//CHECK-NEXT: `-ReturnStmt {{.*}}
+//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue>
+//CHECK-NEXT: `-DeclRefExpr {{.*}} '__fpm8' lvalue Var {{.*}} 'f1n' '__fpm8'
+
+
+/* Class */
+
+class C1 {
+ __fpm8 f1c;
+ static const __fpm8 f2c;
+ volatile __fpm8 f3c;
+public:
+ C1(__fpm8 arg) : f1c(arg), f3c(arg) { }
+ __fpm8 func1c(__fpm8 arg ) {
+ return arg;
+ }
+ static __fpm8 func2c(__fpm8 arg) {
+ return arg;
+ }
+};
+
+//CHECK: | |-CXXRecordDecl {{.*}} referenced class C1
+//CHECK-NEXT: | |-FieldDecl {{.*}} f1c '__fpm8'
+//CHECK-NEXT: | |-VarDecl {{.*}} f2c 'const __fpm8' static
+//CHECK-NEXT: | |-FieldDecl {{.*}} f3c 'volatile __fpm8'
+//CHECK-NEXT: | |-AccessSpecDecl {{.*}}
+//CHECK-NEXT: | |-CXXConstructorDecl {{.*}} C1 'void (__fpm8)' implicit-inline
+//CHECK-NEXT: | | |-ParmVarDecl {{.*}} arg '__fpm8'
+//CHECK-NEXT: | | |-CXXCtorInitializer {{.*}} 'f1c' '__fpm8'
+//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue>
+//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '__fpm8' lvalue ParmVar {{.*}} 'arg' '__fpm8'
+//CHECK-NEXT: | | |-CXXCtorInitializer {{.*}} 'f3c' 'volatile __fpm8'
+//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue>
+//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '__fpm8' lvalue ParmVar {{.*}} 'arg' '__fpm8'
+//CHECK-NEXT: | | `-CompoundStmt {{.*}}
+//CHECK-NEXT: | |-CXXMethodDecl {{.*}} func1c '__fpm8 (__fpm8)' implicit-inline
+//CHECK-NEXT: | | |-ParmVarDecl {{.*}} arg '__fpm8'
+//CHECK-NEXT: | | `-CompoundStmt {{.*}}
+//CHECK-NEXT: | | `-ReturnStmt {{.*}}
+//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue>
+//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '__fpm8' lvalue ParmVar {{.*}}8 'arg' '__fpm8'
+//CHECK-NEXT: | `-CXXMethodDecl {{.*}} func2c '__fpm8 (__fpm8)' static implicit-inline
+//CHECK-NEXT: | |-ParmVarDecl {{.*}} arg '__fpm8'
+//CHECK-NEXT: | `-CompoundStmt {{.*}}
+//CHECK-NEXT: | `-ReturnStmt {{.*}}
+//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fpm8' <LValueToRValue>
+//CHECK-NEXT: | `-DeclRefExpr {{.*}} '__fpm8' lvalue ParmVar {{.*}} 'arg' '__fpm8'
+
+template <class C> struct S1 {
+ C mem1;
+};
+
+template <> struct S1<__fpm8> {
+ __fpm8 mem2;
+};
+
+//CHECK: |-TemplateArgument type '__fpm8'
+//CHECK-NEXT: | `-BuiltinType {{.*}} '__fpm8'
+//CHECK-NEXT: |-CXXRecordDecl {{.*}} implicit struct S1
+//CHECK-NEXT: `-FieldDecl {{.*}} mem2 '__fpm8'
diff --git a/clang/test/CodeGen/fpm8_opaque.c b/clang/test/CodeGen/fpm8_opaque.c
new file mode 100644
index 0000000000000..19b5128b8eff9
--- /dev/null
+++ b/clang/test/CodeGen/fpm8_opaque.c
@@ -0,0 +1,24 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define dso_local i8 @func1n(
+// CHECK-SAME: i8 noundef [[FPM8:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[FPM8_ADDR:%.*]] = alloca i8, align 1
+// CHECK-NEXT: [[F1N:%.*]] = alloca [10 x i8], align 1
+// CHECK-NEXT: store i8 [[FPM8]], ptr [[FPM8_ADDR]], align 1
+// CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[FPM8_ADDR]], align 1
+// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x i8], ptr [[F1N]], i64 0, i64 2
+// CHECK-NEXT: store i8 [[TMP0]], ptr [[ARRAYIDX]], align 1
+// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [10 x i8], ptr [[F1N]], i64 0, i64 2
+// CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
+// CHECK-NEXT: ret i8 [[TMP1]]
+//
+__fpm8 func1n(__fpm8 fpm8) {
+ __fpm8 f1n[10];
+ f1n[2] = fpm8;
+ return f1n[2];
+}
+
+
+
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Just to add the commit message needs updating to reflect the updated specification. |
0898f1c
to
628752f
Compare
628752f
to
edf2f6c
Compare
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.
Sorry, my comments are a bit all over the place, but I'm concerned we've not defined enough (and/or I need to understand what it means to be a storage only type) for me to confidently accept this PR.
If possible, my suggestion is to detach the scalar type support from the vector type support because I think the vector side of things is more complete from a specification point of view.
042c77a
to
d009e7b
Compare
ARM ACLE PR#323[1] adds new modal types for 8-bit floating point intrinsic. From the PR#323: ``` ACLE defines the `__mfp8` type, which can be used for the E5M2 and E4M3 8-bit floating-point formats. It is a storage and interchange only type with no arithmetic operations other than intrinsic calls. ```` The type should be an opaque type and its format in undefined in Clang. Only defined in the backend by a status/format register, for AArch64 the FPMR. This patch is an attempt to the add the MFloat8_t scalar type. It has a parser and codegen for the new scalar type. The patch it is lowering to and 8bit unsigned as it has no format. But maybe we should add another opaque type. [1] ARM-software/acle#323
d009e7b
to
eb12648
Compare
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/140/builds/9464 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/12/builds/8311 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/144/builds/10108 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/133/builds/5703 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/3/builds/6669 Here is the relevant piece of the build log for the reference
|
This patch fix the failing tests by adding REQUIRES: aarch64-registered-target This tests was failing in non aarch64 cpu. The test was introduced by: [CLANG][AArch64] Add the modal 8 bit floating-point scalar type (#97277)
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/46/builds/6850 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/154/builds/6441 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/27/builds/1021 Here is the relevant piece of the build log for the reference
|
FYI Arm 32 bit is failing on a different test than most of these - https://lab.llvm.org/buildbot/#/builders/154/builds/6442 That bot only enables the Arm target, if that makes any difference. The test asks Arm and/or AArch64 but maybe the implementation has problems when only one is enabled? |
//CHECK-NEXT: | | `-CompoundStmt {{.*}} | ||
//CHECK-NEXT: | | `-ReturnStmt {{.*}} | ||
//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '__mfp8':'__MFloat8_t' <LValueToRValue> | ||
//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '__mfp8':'__MFloat8_t' lvalue ParmVar {{.*}}8 'arg' '__mfp8':'__MFloat8_t' |
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.
Perhaps this }8
is a typo and it should be {{.*}}
only? I will try it locally.
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.
It's perhaps because the test uses aarch64-registered-target || arm-registered-target
for what's effectively an AArch64 specific test. From what I can see there are many such tests that are miss classified but I guess fp8 being strictly AArch64 specific means this is the first time we get an explicit failure?
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.
The test passed with the 8 removed so I committed 81e536e. As the number its checking doesn't seem to be significant. I can revert if that's going to cause other problems.
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.
If I recall correctly, clang can always produce IR or AST in this case, for a given target triple regardless of the backends included. So the aarch64-registered-target || arm-registered-target
is probably just so including arm_neon.h
doesn't error?
If you actually tried to use the fp8 stuff on Arm 32, you'd have other problems I assume.
New test added by #97277.
…#97277) ARM ACLE PR#323[1] adds new modal types for 8-bit floating point intrinsic. From the PR#323: ``` ACLE defines the `__mfp8` type, which can be used for the E5M2 and E4M3 8-bit floating-point formats. It is a storage and interchange only type with no arithmetic operations other than intrinsic calls. ```` The type should be an opaque type and its format in undefined in Clang. Only defined in the backend by a status/format register, for AArch64 the FPMR. This patch is an attempt to the add the mfloat8_t scalar type. It has a parser and codegen for the new scalar type. The patch it is lowering to and 8bit unsigned as it has no format. But maybe we should add another opaque type. [1] ARM-software/acle#323
This patch fix the failing tests by adding REQUIRES: aarch64-registered-target This tests was failing in non aarch64 cpu. The test was introduced by: [CLANG][AArch64] Add the modal 8 bit floating-point scalar type (llvm#97277)
New test added by llvm#97277.
ARM ACLE PR#323[1] adds new modal types for 8-bit floating point intrinsic.
From the PR#323:
The type should be an opaque type and its format in undefined in Clang. Only defined in the backend by a status/format register, for AArch64 the FPMR.
This patch is an attempt to the add the mfloat8_t scalar type. It has a parser and codegen for the new scalar type.
The patch it is lowering to and 8bit unsigned as it has no format. But maybe we should add another opaque type.
[1] ARM-software/acle#323