[NFC][Clang][AArch64]Refactor implementation of Neon vectors MFloat8… (#114804)

…x8 and MFloat8x16

This patch adds MFloat8 as a TypeFlag and Kind on Neon to generate the
typedefs using emitNeonTypeDefs.
It does not need any change in Clang, because SEMA and CodeGen use the
Builtins defined in AArch64SVEACLETypes.def
This commit is contained in:
CarolineConcatto 2024-11-21 10:29:28 +00:00 committed by GitHub
parent ef102b4a63
commit aaba8406c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 18 deletions

View File

@ -218,6 +218,7 @@ def OP_UNAVAILABLE : Operation {
// h: half-float
// d: double
// b: bfloat16
// m: mfloat8
//
// Typespec modifiers
// ------------------

View File

@ -101,7 +101,8 @@ enum EltType {
Float16,
Float32,
Float64,
BFloat16
BFloat16,
MFloat8 // Not used by Sema or CodeGen in Clang
};
} // end namespace NeonTypeFlags
@ -143,14 +144,7 @@ class Type {
private:
TypeSpec TS;
enum TypeKind {
Void,
Float,
SInt,
UInt,
Poly,
BFloat16
};
enum TypeKind { Void, Float, SInt, UInt, Poly, BFloat16, MFloat8 };
TypeKind Kind;
bool Immediate, Constant, Pointer;
// ScalarForMangling and NoManglingQ are really not suited to live here as
@ -203,6 +197,7 @@ public:
bool isLong() const { return isInteger() && ElementBitwidth == 64; }
bool isVoid() const { return Kind == Void; }
bool isBFloat16() const { return Kind == BFloat16; }
bool isMFloat8() const { return Kind == MFloat8; }
unsigned getNumElements() const { return Bitwidth / ElementBitwidth; }
unsigned getSizeInBits() const { return Bitwidth; }
unsigned getElementSizeInBits() const { return ElementBitwidth; }
@ -657,6 +652,8 @@ std::string Type::str() const {
S += "float";
else if (isBFloat16())
S += "bfloat";
else if (isMFloat8())
S += "mfloat";
else
S += "int";
@ -699,6 +696,9 @@ std::string Type::builtin_str() const {
else if (isBFloat16()) {
assert(ElementBitwidth == 16 && "BFloat16 can only be 16 bits");
S += "y";
} else if (isMFloat8()) {
assert(ElementBitwidth == 8 && "MFloat8 can only be 8 bits");
S += "m";
} else
switch (ElementBitwidth) {
case 16: S += "h"; break;
@ -758,6 +758,10 @@ unsigned Type::getNeonEnum() const {
Base = (unsigned)NeonTypeFlags::BFloat16;
}
if (isMFloat8()) {
Base = (unsigned)NeonTypeFlags::MFloat8;
}
if (Bitwidth == 128)
Base |= (unsigned)NeonTypeFlags::QuadFlag;
if (isInteger() && !isSigned())
@ -779,6 +783,8 @@ Type Type::fromTypedefName(StringRef Name) {
T.Kind = Poly;
} else if (Name.consume_front("bfloat")) {
T.Kind = BFloat16;
} else if (Name.consume_front("mfloat")) {
T.Kind = MFloat8;
} else {
assert(Name.starts_with("int"));
Name = Name.drop_front(3);
@ -879,6 +885,10 @@ void Type::applyTypespec(bool &Quad) {
Kind = BFloat16;
ElementBitwidth = 16;
break;
case 'm':
Kind = MFloat8;
ElementBitwidth = 8;
break;
default:
llvm_unreachable("Unhandled type code!");
}
@ -993,6 +1003,9 @@ std::string Intrinsic::getInstTypeCode(Type T, ClassKind CK) const {
if (T.isBFloat16())
return "bf16";
if (T.isMFloat8())
return "mfp8";
if (T.isPoly())
typeCode = 'p';
else if (T.isInteger())
@ -1030,7 +1043,7 @@ std::string Intrinsic::getBuiltinTypeStr() {
Type RetT = getReturnType();
if ((LocalCK == ClassI || LocalCK == ClassW) && RetT.isScalar() &&
!RetT.isFloating() && !RetT.isBFloat16())
!RetT.isFloating() && !RetT.isBFloat16() && !RetT.isMFloat8())
RetT.makeInteger(RetT.getElementSizeInBits(), false);
// Since the return value must be one type, return a vector type of the
@ -2270,7 +2283,7 @@ static void emitNeonTypeDefs(const std::string& types, raw_ostream &OS) {
for (auto &TS : TDTypeVec) {
bool IsA64 = false;
Type T(TS, ".");
if (T.isDouble())
if (T.isDouble() || T.isMFloat8())
IsA64 = true;
if (InIfdef && !IsA64) {
@ -2282,15 +2295,20 @@ static void emitNeonTypeDefs(const std::string& types, raw_ostream &OS) {
InIfdef = true;
}
if (T.isPoly())
if (T.isMFloat8())
OS << "typedef __MFloat8x";
else if (T.isPoly())
OS << "typedef __attribute__((neon_polyvector_type(";
else
OS << "typedef __attribute__((neon_vector_type(";
Type T2 = T;
T2.makeScalar();
OS << T.getNumElements() << "))) ";
OS << T2.str();
OS << T.getNumElements();
if (T.isMFloat8())
OS << "_t ";
else
OS << "))) " << T2.str();
OS << " " << T.str() << ";\n";
}
if (InIfdef)
@ -2303,7 +2321,7 @@ static void emitNeonTypeDefs(const std::string& types, raw_ostream &OS) {
for (auto &TS : TDTypeVec) {
bool IsA64 = false;
Type T(TS, ".");
if (T.isDouble())
if (T.isDouble() || T.isMFloat8())
IsA64 = true;
if (InIfdef && !IsA64) {
@ -2589,8 +2607,6 @@ void NeonEmitter::runVectorTypes(raw_ostream &OS) {
OS << "#if defined(__aarch64__) || defined(__arm64ec__)\n";
OS << "typedef __mfp8 mfloat8_t;\n";
OS << "typedef __MFloat8x8_t mfloat8x8_t;\n";
OS << "typedef __MFloat8x16_t mfloat8x16_t;\n";
OS << "typedef double float64_t;\n";
OS << "#endif\n\n";
@ -2648,7 +2664,7 @@ __arm_set_fpm_lscale2(fpm_t __fpm, uint64_t __scale) {
)";
emitNeonTypeDefs("cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfdQd", OS);
emitNeonTypeDefs("cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlmQmhQhfQfdQd", OS);
emitNeonTypeDefs("bQb", OS);
OS << "#endif // __ARM_NEON_TYPES_H\n";