Skip to content

Commit

Permalink
[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 `__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
  • Loading branch information
CarolineConcatto committed Sep 21, 2024
1 parent 3e32e45 commit edf2f6c
Show file tree
Hide file tree
Showing 30 changed files with 293 additions and 8 deletions.
7 changes: 7 additions & 0 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -2644,6 +2644,8 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
bool isQueueT() const; // OpenCL queue_t
bool isReserveIDT() const; // OpenCL reserve_id_t

bool isArmMFloat8Type() const; // AARCH64_OPAQUE_TYPE

#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
bool is##Id##Type() const;
#include "clang/Basic/OpenCLExtensionTypes.def"
Expand Down Expand Up @@ -8312,6 +8314,11 @@ inline bool Type::isBitIntType() const {
return isa<BitIntType>(CanonicalType);
}

// AARCH64_OPAQUE_TYPE
inline bool Type::isArmMFloat8Type() const {
return isSpecificBuiltinType(BuiltinType::ArmMFloat8);
}

#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
inline bool Type::is##Id##Type() const { \
return isSpecificBuiltinType(BuiltinType::Id); \
Expand Down
9 changes: 9 additions & 0 deletions clang/include/clang/Basic/AArch64SVEACLETypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@
SVE_TYPE(Name, Id, SingletonId)
#endif

#ifndef AARCH64_OPAQUE_TYPE
#define AARCH64_OPAQUE_TYPE(Name, MangledName, Id, SingletonId, NumEls, \
ElBits, NF) \
SVE_TYPE(Name, Id, SingletonId)
#endif

//===- Vector point types -----------------------------------------------===//

SVE_VECTOR_TYPE_INT("__SVInt8_t", "__SVInt8_t", SveInt8, SveInt8Ty, 16, 8, 1, true)
Expand Down Expand Up @@ -181,11 +187,14 @@ SVE_PREDICATE_TYPE_ALL("__clang_svboolx4_t", "svboolx4_t", SveBoolx4, SveBoolx4T

SVE_OPAQUE_TYPE("__SVCount_t", "__SVCount_t", SveCount, SveCountTy)

AARCH64_OPAQUE_TYPE("__MFloat8_t", "__MFloat8_t", ArmMFloat8, ArmMFloat8Ty, 1, 8, 1)

#undef SVE_VECTOR_TYPE
#undef SVE_VECTOR_TYPE_BFLOAT
#undef SVE_VECTOR_TYPE_FLOAT
#undef SVE_VECTOR_TYPE_INT
#undef SVE_PREDICATE_TYPE
#undef SVE_PREDICATE_TYPE_ALL
#undef SVE_OPAQUE_TYPE
#undef AARCH64_OPAQUE_TYPE
#undef SVE_TYPE
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -7931,6 +7931,8 @@ def err_bad_lvalue_to_rvalue_cast : Error<
def err_bad_rvalue_to_rvalue_cast : Error<
"cannot cast from rvalue of type %1 to rvalue reference type %2; types are "
"not compatible">;
def err_bad_mfloat8_cast : Error<
"cannot cast %0 to %1; types are not compatible">;
def err_bad_static_cast_pointer_nonpointer : Error<
"cannot cast from type %1 to pointer type %2">;
def err_bad_static_cast_member_pointer_nonmp : Error<
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_ArmMFloat8_t, // AARCH64_OPAQUE_TYPE
TST_float,
TST_double,
TST_float128,
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ class TargetInfo : public TransferrableTargetInfo,
bool HasFullBFloat16; // True if the backend supports native bfloat16
// arithmetic. Used to determine excess precision
// support in the frontend.
bool HasMFloat8;
bool HasIbm128;
bool HasLongDouble;
bool HasFPReturn;
Expand Down Expand Up @@ -700,6 +701,9 @@ class TargetInfo : public TransferrableTargetInfo,
return HasBFloat16 || HasFullBFloat16;
}

/// Determine whether the _mfp8 type is supported on this target.
virtual bool hasArmMFloat8Type() const { return HasMFloat8; }

/// Determine whether the BFloat type is fully supported on this target, i.e
/// arithemtic operations.
virtual bool hasFullBFloat16Type() const { return HasFullBFloat16; }
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 @@ -675,6 +675,7 @@ KEYWORD(__bool , KEYALTIVEC|KEYZVECTOR)
// ARM NEON extensions.
ALIAS("__fp16", half , KEYALL)
KEYWORD(__bf16 , KEYALL)
KEYWORD(__mfp8 , KEYALL)

// OpenCL Extension.
KEYWORD(half , HALFSUPPORT)
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Sema/DeclSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@ class DeclSpec {
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
static const TST TST_##Name = clang::TST_##Name;
#include "clang/Basic/HLSLIntangibleTypes.def"
// AARCH64_OPAQUE_TYPE
static const TST TST_ArmMFloat8_t = clang::TST_ArmMFloat8_t;
static const TST TST_error = clang::TST_error;

// type-qualifiers
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,7 @@ enum PredefinedTypeIDs {
///
/// Type IDs for non-predefined types will start at
/// NUM_PREDEF_TYPE_IDs.
const unsigned NUM_PREDEF_TYPE_IDS = 505;
const unsigned NUM_PREDEF_TYPE_IDS = 506;

// Ensure we do not overrun the predefined types we reserved
// in the enum PredefinedTypeIDs above.
Expand Down
13 changes: 12 additions & 1 deletion clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1391,7 +1391,8 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
}

if (Target.hasAArch64SVETypes() ||
(AuxTarget && AuxTarget->hasAArch64SVETypes())) {
(AuxTarget && AuxTarget->hasAArch64SVETypes()) ||
Target.hasArmMFloat8Type()) {
#define SVE_TYPE(Name, Id, SingletonId) \
InitBuiltinType(SingletonId, BuiltinType::Id);
#include "clang/Basic/AArch64SVEACLETypes.def"
Expand Down Expand Up @@ -2218,6 +2219,12 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = 0; \
Align = 16; \
break;
#define AARCH64_OPAQUE_TYPE(Name, MangledName, Id, SingletonId, NumEls, \
ElBits, NF)
case BuiltinType::ArmMFloat8:
Width = Target->getCharWidth();
Align = Target->getCharAlign();
break;
#include "clang/Basic/AArch64SVEACLETypes.def"
#define PPC_VECTOR_TYPE(Name, Id, Size) \
case BuiltinType::Id: \
Expand Down Expand Up @@ -4302,6 +4309,8 @@ ASTContext::getBuiltinVectorTypeInfo(const BuiltinType *Ty) const {
case BuiltinType::Id: \
return {BoolTy, llvm::ElementCount::getScalable(NumEls), NF};
#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId)
#define AARCH64_OPAQUE_TYPE(Name, MangledName, Id, SingletonId, NumEls, \
ElBits, NF)
#include "clang/Basic/AArch64SVEACLETypes.def"

#define RVV_VECTOR_TYPE_INT(Name, Id, SingletonId, NumEls, ElBits, NF, \
Expand Down Expand Up @@ -4367,6 +4376,8 @@ QualType ASTContext::getScalableVectorType(QualType EltTy, unsigned NumElts,
if (EltTy->isBooleanType() && NumElts == (NumEls * NF) && NumFields == 1) \
return SingletonId;
#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId)
#define AARCH64_OPAQUE_TYPE(Name, MangledName, Id, SingletonId, NumEls, \
ElBits, NF)
#include "clang/Basic/AArch64SVEACLETypes.def"
} else if (Target->hasRISCVVTypes()) {
uint64_t EltTySize = getTypeSize(EltTy);
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3406,6 +3406,12 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
type_name = MangledName; \
Out << (type_name == Name ? "u" : "") << type_name.size() << type_name; \
break;
#define AARCH64_OPAQUE_TYPE(Name, MangledName, Id, SingletonId, NumEls, \
ElBits, NF) \
case BuiltinType::Id: \
type_name = MangledName; \
Out << (type_name == Name ? "u" : "") << type_name.size() << type_name; \
break;
#include "clang/Basic/AArch64SVEACLETypes.def"
#define PPC_VECTOR_TYPE(Name, Id, Size) \
case BuiltinType::Id: \
Expand Down
25 changes: 22 additions & 3 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2484,9 +2484,18 @@ bool Type::isSVESizelessBuiltinType() const {
if (const BuiltinType *BT = getAs<BuiltinType>()) {
switch (BT->getKind()) {
// SVE Types
#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \
case BuiltinType::Id:
#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \
case BuiltinType::Id:
#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \
case BuiltinType::Id:
#define AARCH64_OPAQUE_TYPE(Name, MangledName, Id, SingletonId, NumEls, \
ElBits, NF)
#include "clang/Basic/AArch64SVEACLETypes.def"
return true;
case BuiltinType::ArmMFloat8:
return false;
default:
return false;
}
Expand Down Expand Up @@ -3437,9 +3446,19 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
case Id: \
return #ExtType;
#include "clang/Basic/OpenCLExtensionTypes.def"
#define SVE_TYPE(Name, Id, SingletonId) \
case Id: \
#define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \
case Id: \
return Name;
#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \
case Id: \
return Name;
#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \
case Id: \
return Name;
#define AARCH64_OPAQUE_TYPE(Name, MangledName, Id, SingletonId, NumEls, \
ElBits, NF)
case ArmMFloat8:
return "__mfp8";
#include "clang/Basic/AArch64SVEACLETypes.def"
#define PPC_VECTOR_TYPE(Name, Id, Size) \
case Id: \
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
NoAsmVariants = false;
HasLegalHalfType = false;
HalfArgsAndReturns = false;
HasMFloat8 = false;
HasFloat128 = false;
HasIbm128 = false;
HasFloat16 = false;
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,7 @@ bool AArch64TargetInfo::hasFeature(StringRef Feature) const {
.Case("sha3", HasSHA3)
.Cases("aes", "pmull", HasAES)
.Cases("fp16", "fullfp16", HasFullFP16)
.Case("fp8", HasMFloat8)
.Case("dit", HasDIT)
.Case("dpb", HasCCPP)
.Case("dpb2", HasCCDP)
Expand Down Expand Up @@ -988,6 +989,9 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
FPU |= NeonMode;
HasSM4 = true;
}
if (Feature == "+fp8") {
HasMFloat8 = true;
}
if (Feature == "+strict-align")
HasUnalignedAccess = false;

Expand Down Expand Up @@ -1229,6 +1233,8 @@ bool AArch64TargetInfo::hasBFloat16Type() const {
return true;
}

bool AArch64TargetInfo::hasArmMFloat8Type() const { return true; }

TargetInfo::CallingConvCheckResult
AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
switch (CC) {
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Basic/Targets/AArch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
bool HasLS64 = false;
bool HasRandGen = false;
bool HasMatMul = false;
bool HasMFloat8 = false;
bool HasBFloat16 = false;
bool HasSVE2 = false;
bool HasSVE2p1 = false;
Expand Down Expand Up @@ -169,6 +170,8 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {

bool hasBFloat16Type() const override;

bool hasArmMFloat8Type() const override;

CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;

bool isCLZForZeroUndef() const override;
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,13 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/AArch64SVEACLETypes.def"
{
if (BT->getKind() == BuiltinType::ArmMFloat8) {
Encoding = llvm::dwarf::DW_ATE_unsigned_char;
BTName = BT->getName(CGM.getLangOpts());
// Bit size and offset of the type.
uint64_t Size = CGM.getContext().getTypeSize(BT);
return DBuilder.createBasicType(BTName, Size, Encoding);
}
ASTContext::BuiltinVectorTypeInfo Info =
// For svcount_t, only the lower 2 bytes are relevant.
BT->getKind() == BuiltinType::SveCount
Expand Down
6 changes: 5 additions & 1 deletion clang/lib/CodeGen/CodeGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,6 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
Context.getFloatTypeSemantics(T),
/* UseNativeHalf = */ false);
break;

case BuiltinType::NullPtr:
// Model std::nullptr_t as i8*
ResultType = llvm::PointerType::getUnqual(getLLVMContext());
Expand Down Expand Up @@ -504,6 +503,8 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
case BuiltinType::Id:
#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \
case BuiltinType::Id:
#define AARCH64_OPAQUE_TYPE(Name, MangledName, Id, SingletonId, NumEls, \
ElBits, NF)
#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId)
#include "clang/Basic/AArch64SVEACLETypes.def"
{
Expand All @@ -526,6 +527,9 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
}
case BuiltinType::SveCount:
return llvm::TargetExtType::get(getLLVMContext(), "aarch64.svcount");
case BuiltinType::ArmMFloat8:
ResultType = llvm::Type::getInt8Ty(getLLVMContext());
break;
#define PPC_VECTOR_TYPE(Name, Id, Size) \
case BuiltinType::Id: \
ResultType = \
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 @@ -4547,6 +4547,10 @@ void Parser::ParseDeclarationSpecifiers(
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,
DiagID, Policy);
break;
case tok::kw___mfp8: // AARCH64_OPAQUE_TYPE
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_ArmMFloat8_t, Loc, PrevSpec,
DiagID, Policy);
break;
case tok::kw_half:
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
DiagID, Policy);
Expand Down Expand Up @@ -5828,6 +5832,7 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
case tok::kw__ExtInt:
case tok::kw__BitInt:
case tok::kw___bf16:
case tok::kw___mfp8:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
Expand Down Expand Up @@ -5913,6 +5918,7 @@ bool Parser::isTypeSpecifierQualifier() {
case tok::kw_int:
case tok::kw__ExtInt:
case tok::kw__BitInt:
case tok::kw___mfp8:
case tok::kw_half:
case tok::kw___bf16:
case tok::kw_float:
Expand Down Expand Up @@ -6137,6 +6143,7 @@ bool Parser::isDeclarationSpecifier(
case tok::kw_int:
case tok::kw__ExtInt:
case tok::kw__BitInt:
case tok::kw___mfp8:
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 @@ -1625,6 +1625,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
case tok::kw__BitInt:
case tok::kw_signed:
case tok::kw_unsigned:
case tok::kw___mfp8:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Parse/ParseExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2408,6 +2408,10 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
case tok::kw___int128:
DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID, Policy);
break;
case tok::kw___mfp8: // AARCH64_OPAQUE_TYPE
DS.SetTypeSpecType(DeclSpec::TST_ArmMFloat8_t, 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 @@ -1788,6 +1788,7 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
case tok::kw_short:
case tok::kw_int:
case tok::kw_long:
case tok::kw___mfp8:
case tok::kw___int64:
case tok::kw___int128:
case tok::kw_signed:
Expand Down Expand Up @@ -1918,6 +1919,7 @@ bool Parser::isCXXDeclarationSpecifierAType() {
case tok::kw_long:
case tok::kw___int64:
case tok::kw___int128:
case tok::kw___mfp8:
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 @@ -379,6 +379,7 @@ bool Declarator::isDeclarationOfFunction() const {
#include "clang/Basic/OpenCLImageTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case TST_##Name:
#include "clang/Basic/HLSLIntangibleTypes.def"
case TST_ArmMFloat8_t: // AARCH64_OPAQUE_TYPE
return false;

case TST_decltype_auto:
Expand Down Expand Up @@ -613,6 +614,8 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
case DeclSpec::TST_##Name: \
return #Name;
case DeclSpec::TST_ArmMFloat8_t: // AARCH64_OPAQUE_TYPE
return "__mfp8";
#include "clang/Basic/HLSLIntangibleTypes.def"
case DeclSpec::TST_error: return "(error)";
}
Expand Down
Loading

0 comments on commit edf2f6c

Please sign in to comment.