Skip to content

[CLANG][AArch64]Add Neon vectors for mfloat8_t #99865

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

Merged
merged 12 commits into from
Oct 23, 2024
16 changes: 16 additions & 0 deletions clang/include/clang/Basic/AArch64SVEACLETypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -190,11 +201,16 @@ 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
#undef SVE_VECTOR_TYPE_INT
#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
2 changes: 1 addition & 1 deletion clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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: \
Expand Down Expand Up @@ -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"

Expand Down Expand Up @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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: \
Expand Down
14 changes: 12 additions & 2 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2484,9 +2484,19 @@ 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: \
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;
}
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CodeGen/CodeGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
{
Expand Down
51 changes: 51 additions & 0 deletions clang/test/CodeGen/arm-mfp8.c
Original file line number Diff line number Diff line change
@@ -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 <arm_neon.h>

// 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: {{.*}}
2 changes: 1 addition & 1 deletion clang/test/Modules/no-external-type-id.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export module b;
import a;
export int b();

// CHECK: <DECL_FUNCTION {{.*}} op8=4088
// CHECK: <DECL_FUNCTION {{.*}} op8=4104
// CHECK: <TYPE_FUNCTION_PROTO

//--- a.v1.cppm
Expand Down
22 changes: 20 additions & 2 deletions clang/test/Sema/arm-mfp8.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify=sve -triple aarch64-arm-none-eabi \
// RUN: -target-feature -fp8 -target-feature +sve %s
// RUN: %clang_cc1 -fsyntax-only -verify=sve,neon -triple aarch64-arm-none-eabi \
// RUN: -target-feature -fp8 -target-feature +sve -target-feature +neon %s

// REQUIRES: aarch64-registered-target

Expand All @@ -11,3 +11,21 @@ void test_vector_sve(svmfloat8_t a, svuint8_t c) {
a / c; // sve-error {{cannot convert between vector type 'svuint8_t' (aka '__SVUint8_t') and vector type 'svmfloat8_t' (aka '__SVMfloat8_t') as implicit conversion would cause truncation}}
}


#include <arm_neon.h>

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'))}}
}
4 changes: 3 additions & 1 deletion clang/utils/TableGen/NeonEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class Type {
SInt,
UInt,
Poly,
BFloat16,
BFloat16
};
TypeKind Kind;
bool Immediate, Constant, Pointer;
Expand Down Expand Up @@ -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";
Comment on lines +2591 to +2592
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for the new types to be guarded? When looking at arm_vector_types.h the guards are only used for float64 based types, with the other vector types unguarded.

Also, and this might necessitate reintroducing some of the code you were asked to remove, I'd rather emitNeonTypeDefs have the capability to emit the typedefs because that'll verify we have the necessary TypeSpec plumbing required to add the builtins.

Copy link
Contributor

@SpencerAbson SpencerAbson Oct 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I was keen to remove the TypeSpec stuff as it was not used at all, but these typedefs should probably be emitted by emitNeonTypeDefs as they are.. well, still Neon types after all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if we dont want to protect that to 64 bits architecture, then I have to change Sema and ASTContext to introduce the neon type for other architectures that are not 64 bits. Otherwise they fail, because the typedef and the builtin are only introduced/added when Target.hasAArch64SVETypes.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I hadn't realised this was a shared header with arm as well as aarch64. Fair enough, I retract my comment.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it still possible to make use of emitNeonTypeDefs? I can see that also emits the inclusion guards when necessary.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on an offline conversation it has been agreed to wait for the scalar type to land before trying to extend emitNeonTypeDefs and thus this PR can continue as is..

OS << "typedef double float64_t;\n";
OS << "#endif\n\n";

Expand Down
Loading