diff --git a/clang/include/clang/Basic/AArch64SVEACLETypes.def b/clang/include/clang/Basic/AArch64SVEACLETypes.def index 2b80e43b50638..25abf5f3f86b7 100644 --- a/clang/include/clang/Basic/AArch64SVEACLETypes.def +++ b/clang/include/clang/Basic/AArch64SVEACLETypes.def @@ -97,6 +97,17 @@ SVE_TYPE(Name, Id, SingletonId) #endif +#ifndef AARCH64_VECTOR_TYPE +#define AARCH64_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \ + SVE_TYPE(Name, Id, SingletonId) +#endif + +#ifndef AARCH64_VECTOR_TYPE_MFLOAT +#define AARCH64_VECTOR_TYPE_MFLOAT(Name, MangledName, Id, SingletonId, NumEls, ElBits, NF) \ + AARCH64_VECTOR_TYPE(Name, MangledName, Id, SingletonId) +#endif + + //===- Vector point types -----------------------------------------------===// SVE_VECTOR_TYPE_INT("__SVInt8_t", "__SVInt8_t", SveInt8, SveInt8Ty, 16, 8, 1, true) @@ -190,6 +201,9 @@ SVE_PREDICATE_TYPE_ALL("__clang_svboolx4_t", "svboolx4_t", SveBoolx4, SveBoolx4T SVE_OPAQUE_TYPE("__SVCount_t", "__SVCount_t", SveCount, SveCountTy) +AARCH64_VECTOR_TYPE_MFLOAT("__MFloat8x8_t", "__MFloat8x8_t", MFloat8x8, MFloat8x8Ty, 8, 8, 1) +AARCH64_VECTOR_TYPE_MFLOAT("__MFloat8x16_t", "__MFloat8x16_t", MFloat8x16, MFloat8x16Ty, 16, 8, 1) + #undef SVE_VECTOR_TYPE #undef SVE_VECTOR_TYPE_BFLOAT #undef SVE_VECTOR_TYPE_FLOAT @@ -197,4 +211,6 @@ SVE_OPAQUE_TYPE("__SVCount_t", "__SVCount_t", SveCount, SveCountTy) #undef SVE_PREDICATE_TYPE #undef SVE_PREDICATE_TYPE_ALL #undef SVE_OPAQUE_TYPE +#undef AARCH64_VECTOR_TYPE_MFLOAT +#undef AARCH64_VECTOR_TYPE #undef SVE_TYPE diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index e397dff097652..13173dc96e71a 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1149,7 +1149,7 @@ enum PredefinedTypeIDs { /// /// Type IDs for non-predefined types will start at /// NUM_PREDEF_TYPE_IDs. -const unsigned NUM_PREDEF_TYPE_IDS = 509; +const unsigned NUM_PREDEF_TYPE_IDS = 511; // 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 4bf8ddd762e9a..a4e8d95035b97 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2239,6 +2239,12 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { Width = 0; \ Align = 16; \ break; +#define AARCH64_VECTOR_TYPE_MFLOAT(Name, MangledName, Id, SingletonId, NumEls, \ + ElBits, NF) \ + case BuiltinType::Id: \ + Width = NumEls * ElBits * NF; \ + Align = NumEls * ElBits; \ + break; #include "clang/Basic/AArch64SVEACLETypes.def" #define PPC_VECTOR_TYPE(Name, Id, Size) \ case BuiltinType::Id: \ @@ -4361,6 +4367,11 @@ ASTContext::getBuiltinVectorTypeInfo(const BuiltinType *Ty) const { #define SVE_PREDICATE_TYPE_ALL(Name, MangledName, Id, SingletonId, NumEls, NF) \ case BuiltinType::Id: \ return {BoolTy, llvm::ElementCount::getScalable(NumEls), NF}; +#define AARCH64_VECTOR_TYPE_MFLOAT(Name, MangledName, Id, SingletonId, NumEls, \ + ElBits, NF) \ + case BuiltinType::Id: \ + return {getIntTypeForBitwidth(ElBits, false), \ + llvm::ElementCount::getFixed(NumEls), NF}; #define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) #include "clang/Basic/AArch64SVEACLETypes.def" @@ -4427,6 +4438,7 @@ 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_VECTOR_TYPE(Name, MangledName, Id, SingletonId) #include "clang/Basic/AArch64SVEACLETypes.def" } else if (Target->hasRISCVVTypes()) { uint64_t EltTySize = getTypeSize(EltTy); diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index d3ed35deb2b1d..b3e46508cf596 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3430,6 +3430,11 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { type_name = MangledName; \ Out << (type_name == Name ? "u" : "") << type_name.size() << type_name; \ break; +#define AARCH64_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \ + 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: \ diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 5232efae4e363..1b5b5a7a3e503 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2484,9 +2484,19 @@ bool Type::isSVESizelessBuiltinType() const { if (const BuiltinType *BT = getAs()) { 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: \ + return true; +#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \ + case BuiltinType::Id: \ + return true; +#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \ + case BuiltinType::Id: \ + return true; +#define AARCH64_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \ + case BuiltinType::Id: \ + return false; #include "clang/Basic/AArch64SVEACLETypes.def" - return true; default: return false; } diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index 54aa1d59d351a..f87184fc77832 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -505,6 +505,8 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { case BuiltinType::Id: #define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \ case BuiltinType::Id: +#define AARCH64_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \ + case BuiltinType::Id: #define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) #include "clang/Basic/AArch64SVEACLETypes.def" { diff --git a/clang/test/CodeGen/arm-mfp8.c b/clang/test/CodeGen/arm-mfp8.c new file mode 100644 index 0000000000000..35ec24c8a7880 --- /dev/null +++ b/clang/test/CodeGen/arm-mfp8.c @@ -0,0 +1,51 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -emit-llvm -triple aarch64-arm-none-eabi -target-feature -fp8 -target-feature +neon -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-C +// RUN: %clang_cc1 -emit-llvm -triple aarch64-arm-none-eabi -target-feature -fp8 -target-feature +neon -o - -x c++ %s | FileCheck %s --check-prefixes=CHECK,CHECK-CXX + +// REQUIRES: aarch64-registered-target + + +#include + +// CHECK-C-LABEL: define dso_local <16 x i8> @test_ret_mfloat8x16_t( +// CHECK-C-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-C-NEXT: [[ENTRY:.*:]] +// CHECK-C-NEXT: [[V_ADDR:%.*]] = alloca <16 x i8>, align 16 +// CHECK-C-NEXT: store <16 x i8> [[V]], ptr [[V_ADDR]], align 16 +// CHECK-C-NEXT: [[TMP0:%.*]] = load <16 x i8>, ptr [[V_ADDR]], align 16 +// CHECK-C-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z21test_ret_mfloat8x16_tu14__MFloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[V_ADDR:%.*]] = alloca <16 x i8>, align 16 +// CHECK-CXX-NEXT: store <16 x i8> [[V]], ptr [[V_ADDR]], align 16 +// CHECK-CXX-NEXT: [[TMP0:%.*]] = load <16 x i8>, ptr [[V_ADDR]], align 16 +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t test_ret_mfloat8x16_t(mfloat8x16_t v) { + return v; +} + +// CHECK-C-LABEL: define dso_local <8 x i8> @test_ret_mfloat8x8_t( +// CHECK-C-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-C-NEXT: [[ENTRY:.*:]] +// CHECK-C-NEXT: [[V_ADDR:%.*]] = alloca <8 x i8>, align 8 +// CHECK-C-NEXT: store <8 x i8> [[V]], ptr [[V_ADDR]], align 8 +// CHECK-C-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[V_ADDR]], align 8 +// CHECK-C-NEXT: ret <8 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z20test_ret_mfloat8x8_tu13__MFloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[V_ADDR:%.*]] = alloca <8 x i8>, align 8 +// CHECK-CXX-NEXT: store <8 x i8> [[V]], ptr [[V_ADDR]], align 8 +// CHECK-CXX-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[V_ADDR]], align 8 +// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]] +// +mfloat8x8_t test_ret_mfloat8x8_t(mfloat8x8_t v) { + return v; +} + +//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +// CHECK: {{.*}} diff --git a/clang/test/Modules/no-external-type-id.cppm b/clang/test/Modules/no-external-type-id.cppm index 577b97f5930e7..b8b987403812f 100644 --- a/clang/test/Modules/no-external-type-id.cppm +++ b/clang/test/Modules/no-external-type-id.cppm @@ -23,7 +23,7 @@ export module b; import a; export int b(); -// CHECK: + +void test_vector(mfloat8x8_t a, mfloat8x16_t b, uint8x8_t c) { + a + b; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} + a - b; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} + a * b; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} + a / b; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} + + a + c; // neon-error {{cannot convert between vector and non-scalar values ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'uint8x8_t' (vector of 8 'uint8_t' values))}} + a - c; // neon-error {{cannot convert between vector and non-scalar values ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'uint8x8_t' (vector of 8 'uint8_t' values))}} + a * c; // neon-error {{cannot convert between vector and non-scalar values ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'uint8x8_t' (vector of 8 'uint8_t' values))}} + a / c; // neon-error {{cannot convert between vector and non-scalar values ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'uint8x8_t' (vector of 8 'uint8_t' values))}} + c + b; // neon-error {{cannot convert between vector and non-scalar values ('uint8x8_t' (vector of 8 'uint8_t' values) and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} + c - b; // neon-error {{cannot convert between vector and non-scalar values ('uint8x8_t' (vector of 8 'uint8_t' values) and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} + c * b; // neon-error {{cannot convert between vector and non-scalar values ('uint8x8_t' (vector of 8 'uint8_t' values) and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} + c / b; // neon-error {{cannot convert between vector and non-scalar values ('uint8x8_t' (vector of 8 'uint8_t' values) and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} +} diff --git a/clang/utils/TableGen/NeonEmitter.cpp b/clang/utils/TableGen/NeonEmitter.cpp index adff7c70219bb..59c023ca33606 100644 --- a/clang/utils/TableGen/NeonEmitter.cpp +++ b/clang/utils/TableGen/NeonEmitter.cpp @@ -149,7 +149,7 @@ class Type { SInt, UInt, Poly, - BFloat16, + BFloat16 }; TypeKind Kind; bool Immediate, Constant, Pointer; @@ -2588,6 +2588,8 @@ void NeonEmitter::runVectorTypes(raw_ostream &OS) { OS << "typedef __fp16 float16_t;\n"; OS << "#if defined(__aarch64__) || defined(__arm64ec__)\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";