Skip to content

Commit

Permalink
[WIP][CLANG][AArch64] Add the modal 8 bit floating-point scalar type
Browse files Browse the repository at this point in the history
ARM ACLE PR#323[1] adds new modal types for 8-bit floating point intrinsic.

From the PR#323:
```
ACLE defines the `__fpm8` 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 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.

[1]  ARM-software/acle#323
  • Loading branch information
CarolineConcatto committed Jul 1, 2024
1 parent 9e63632 commit fbeca5c
Show file tree
Hide file tree
Showing 25 changed files with 171 additions and 2 deletions.
1 change: 1 addition & 0 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/AST/BuiltinTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -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'.
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/Specifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Sema/DeclSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/TypeLoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/CodeGen/CodeGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/ItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Index/USRGeneration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Lex/Lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Parse/ParseExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Parse/ParseTentative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/DeclSpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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";
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Sema/SemaTemplateVariadic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Serialization/ASTCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
91 changes: 91 additions & 0 deletions clang/test/AST/fpm8_opaque.cpp
Original file line number Diff line number Diff line change
@@ -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'
Loading

0 comments on commit fbeca5c

Please sign in to comment.