diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2279,9 +2279,15 @@ bool isRVVType() const; + bool isVectorInt64Type() const; bool isVectorFloat16Type() const; + bool isVectorFloat32Type() const; + bool isVectorFloat64Type() const; + bool isRVVInt64Type() const; bool isRVVFloat16Type() const; + bool isRVVFloat32Type() const; + bool isRVVFloat64Type() const; /// Return the implicit lifetime for this type, which must not be dependent. Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; @@ -7164,6 +7170,24 @@ false; // end of boolean or operation. } +inline bool Type::isVectorInt64Type() const { +#define RVV_TYPE(Name, Id, SingletonId) false || +#define RVV_VECTOR_TYPE_INT64(Name, Id, ...) \ + isSpecificBuiltinType(BuiltinType::Id) || + return +#include "clang/Basic/RISCVVTypes.def" + false; // end of boolean or operation. +} + +inline bool Type::isRVVInt64Type() const { +#define RVV_TYPE(Name, Id, SingletonId) false || +#define RVV_VECTOR_TYPE_INT64(Name, Id, ...) \ + isSpecificBuiltinType(BuiltinType::Id) || + return +#include "clang/Basic/RISCVVTypes.def" + false; // end of boolean or operation. +} + inline bool Type::isVectorFloat16Type() const { #define RVV_TYPE(Name, Id, SingletonId) false || #define RVV_VECTOR_TYPE_HALF_FLOAT(Name, Id, ...) \ @@ -7182,6 +7206,42 @@ false; // end of boolean or operation. } +inline bool Type::isVectorFloat32Type() const { +#define RVV_TYPE(Name, Id, SingletonId) false || +#define RVV_VECTOR_TYPE_FLOAT32(Name, Id, ...) \ + isSpecificBuiltinType(BuiltinType::Id) || + return +#include "clang/Basic/RISCVVTypes.def" + false; // end of boolean or operation. +} + +inline bool Type::isRVVFloat32Type() const { +#define RVV_TYPE(Name, Id, SingletonId) false || +#define RVV_VECTOR_TYPE_FLOAT32(Name, Id, ...) \ + isSpecificBuiltinType(BuiltinType::Id) || + return +#include "clang/Basic/RISCVVTypes.def" + false; // end of boolean or operation. +} + +inline bool Type::isVectorFloat64Type() const { +#define RVV_TYPE(Name, Id, SingletonId) false || +#define RVV_VECTOR_TYPE_FLOAT64(Name, Id, ...) \ + isSpecificBuiltinType(BuiltinType::Id) || + return +#include "clang/Basic/RISCVVTypes.def" + false; // end of boolean or operation. +} + +inline bool Type::isRVVFloat64Type() const { +#define RVV_TYPE(Name, Id, SingletonId) false || +#define RVV_VECTOR_TYPE_FLOAT64(Name, Id, ...) \ + isSpecificBuiltinType(BuiltinType::Id) || + return +#include "clang/Basic/RISCVVTypes.def" + false; // end of boolean or operation. +} + inline bool Type::isTemplateTypeParmType() const { return isa(CanonicalType); } diff --git a/clang/include/clang/Basic/RISCVVTypes.def b/clang/include/clang/Basic/RISCVVTypes.def --- a/clang/include/clang/Basic/RISCVVTypes.def +++ b/clang/include/clang/Basic/RISCVVTypes.def @@ -60,10 +60,24 @@ RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, false, true) #endif +// The types below is simply an extra layer of labeling for type checking +// utilities under clang/AST/Type.h. +#ifndef RVV_VECTOR_TYPE_INT64 +#define RVV_VECTOR_TYPE_INT64 RVV_VECTOR_TYPE_INT +#endif + #ifndef RVV_VECTOR_TYPE_HALF_FLOAT #define RVV_VECTOR_TYPE_HALF_FLOAT RVV_VECTOR_TYPE_FLOAT #endif +#ifndef RVV_VECTOR_TYPE_FLOAT32 +#define RVV_VECTOR_TYPE_FLOAT32 RVV_VECTOR_TYPE_FLOAT +#endif + +#ifndef RVV_VECTOR_TYPE_FLOAT64 +#define RVV_VECTOR_TYPE_FLOAT64 RVV_VECTOR_TYPE_FLOAT +#endif + //===- Vector types -------------------------------------------------------===// RVV_VECTOR_TYPE_INT("__rvv_int8mf8_t", RvvInt8mf8, RvvInt8mf8Ty, 1, 8, 1, true) @@ -108,15 +122,15 @@ RVV_VECTOR_TYPE_INT("__rvv_uint32m4_t", RvvUint32m4, RvvUint32m4Ty, 8, 32, 1, false) RVV_VECTOR_TYPE_INT("__rvv_uint32m8_t", RvvUint32m8, RvvUint32m8Ty, 16, 32, 1, false) -RVV_VECTOR_TYPE_INT("__rvv_int64m1_t", RvvInt64m1, RvvInt64m1Ty, 1, 64, 1, true) -RVV_VECTOR_TYPE_INT("__rvv_int64m2_t", RvvInt64m2, RvvInt64m2Ty, 2, 64, 1, true) -RVV_VECTOR_TYPE_INT("__rvv_int64m4_t", RvvInt64m4, RvvInt64m4Ty, 4, 64, 1, true) -RVV_VECTOR_TYPE_INT("__rvv_int64m8_t", RvvInt64m8, RvvInt64m8Ty, 8, 64, 1, true) +RVV_VECTOR_TYPE_INT64("__rvv_int64m1_t", RvvInt64m1, RvvInt64m1Ty, 1, 64, 1, true) +RVV_VECTOR_TYPE_INT64("__rvv_int64m2_t", RvvInt64m2, RvvInt64m2Ty, 2, 64, 1, true) +RVV_VECTOR_TYPE_INT64("__rvv_int64m4_t", RvvInt64m4, RvvInt64m4Ty, 4, 64, 1, true) +RVV_VECTOR_TYPE_INT64("__rvv_int64m8_t", RvvInt64m8, RvvInt64m8Ty, 8, 64, 1, true) -RVV_VECTOR_TYPE_INT("__rvv_uint64m1_t",RvvUint64m1,RvvUint64m1Ty,1, 64, 1, false) -RVV_VECTOR_TYPE_INT("__rvv_uint64m2_t",RvvUint64m2,RvvUint64m2Ty,2, 64, 1, false) -RVV_VECTOR_TYPE_INT("__rvv_uint64m4_t",RvvUint64m4,RvvUint64m4Ty,4, 64, 1, false) -RVV_VECTOR_TYPE_INT("__rvv_uint64m8_t",RvvUint64m8,RvvUint64m8Ty,8, 64, 1, false) +RVV_VECTOR_TYPE_INT64("__rvv_uint64m1_t",RvvUint64m1,RvvUint64m1Ty,1, 64, 1, false) +RVV_VECTOR_TYPE_INT64("__rvv_uint64m2_t",RvvUint64m2,RvvUint64m2Ty,2, 64, 1, false) +RVV_VECTOR_TYPE_INT64("__rvv_uint64m4_t",RvvUint64m4,RvvUint64m4Ty,4, 64, 1, false) +RVV_VECTOR_TYPE_INT64("__rvv_uint64m8_t",RvvUint64m8,RvvUint64m8Ty,8, 64, 1, false) RVV_VECTOR_TYPE_HALF_FLOAT("__rvv_float16mf4_t",RvvFloat16mf4,RvvFloat16mf4Ty,1, 16, 1) RVV_VECTOR_TYPE_HALF_FLOAT("__rvv_float16mf2_t",RvvFloat16mf2,RvvFloat16mf2Ty,2, 16, 1) @@ -125,16 +139,16 @@ RVV_VECTOR_TYPE_HALF_FLOAT("__rvv_float16m4_t", RvvFloat16m4, RvvFloat16m4Ty, 16, 16, 1) RVV_VECTOR_TYPE_HALF_FLOAT("__rvv_float16m8_t", RvvFloat16m8, RvvFloat16m8Ty, 32, 16, 1) -RVV_VECTOR_TYPE_FLOAT("__rvv_float32mf2_t",RvvFloat32mf2,RvvFloat32mf2Ty,1, 32, 1) -RVV_VECTOR_TYPE_FLOAT("__rvv_float32m1_t", RvvFloat32m1, RvvFloat32m1Ty, 2, 32, 1) -RVV_VECTOR_TYPE_FLOAT("__rvv_float32m2_t", RvvFloat32m2, RvvFloat32m2Ty, 4, 32, 1) -RVV_VECTOR_TYPE_FLOAT("__rvv_float32m4_t", RvvFloat32m4, RvvFloat32m4Ty, 8, 32, 1) -RVV_VECTOR_TYPE_FLOAT("__rvv_float32m8_t", RvvFloat32m8, RvvFloat32m8Ty, 16, 32, 1) +RVV_VECTOR_TYPE_FLOAT32("__rvv_float32mf2_t",RvvFloat32mf2,RvvFloat32mf2Ty,1, 32, 1) +RVV_VECTOR_TYPE_FLOAT32("__rvv_float32m1_t", RvvFloat32m1, RvvFloat32m1Ty, 2, 32, 1) +RVV_VECTOR_TYPE_FLOAT32("__rvv_float32m2_t", RvvFloat32m2, RvvFloat32m2Ty, 4, 32, 1) +RVV_VECTOR_TYPE_FLOAT32("__rvv_float32m4_t", RvvFloat32m4, RvvFloat32m4Ty, 8, 32, 1) +RVV_VECTOR_TYPE_FLOAT32("__rvv_float32m8_t", RvvFloat32m8, RvvFloat32m8Ty, 16, 32, 1) -RVV_VECTOR_TYPE_FLOAT("__rvv_float64m1_t", RvvFloat64m1, RvvFloat64m1Ty, 1, 64, 1) -RVV_VECTOR_TYPE_FLOAT("__rvv_float64m2_t", RvvFloat64m2, RvvFloat64m2Ty, 2, 64, 1) -RVV_VECTOR_TYPE_FLOAT("__rvv_float64m4_t", RvvFloat64m4, RvvFloat64m4Ty, 4, 64, 1) -RVV_VECTOR_TYPE_FLOAT("__rvv_float64m8_t", RvvFloat64m8, RvvFloat64m8Ty, 8, 64, 1) +RVV_VECTOR_TYPE_FLOAT64("__rvv_float64m1_t", RvvFloat64m1, RvvFloat64m1Ty, 1, 64, 1) +RVV_VECTOR_TYPE_FLOAT64("__rvv_float64m2_t", RvvFloat64m2, RvvFloat64m2Ty, 2, 64, 1) +RVV_VECTOR_TYPE_FLOAT64("__rvv_float64m4_t", RvvFloat64m4, RvvFloat64m4Ty, 4, 64, 1) +RVV_VECTOR_TYPE_FLOAT64("__rvv_float64m8_t", RvvFloat64m8, RvvFloat64m8Ty, 8, 64, 1) RVV_PREDICATE_TYPE("__rvv_bool1_t", RvvBool1, RvvBool1Ty, 64) RVV_PREDICATE_TYPE("__rvv_bool2_t", RvvBool2, RvvBool2Ty, 32) @@ -145,8 +159,11 @@ RVV_PREDICATE_TYPE("__rvv_bool64_t", RvvBool64, RvvBool64Ty, 1) #undef RVV_VECTOR_TYPE_FLOAT +#undef RVV_VECTOR_TYPE_FLOAT64 +#undef RVV_VECTOR_TYPE_FLOAT32 #undef RVV_VECTOR_TYPE_HALF_FLOAT #undef RVV_VECTOR_TYPE_INT +#undef RVV_VECTOR_TYPE_INT64 #undef RVV_VECTOR_TYPE #undef RVV_PREDICATE_TYPE #undef RVV_TYPE diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -664,10 +664,19 @@ /// Determine whether constrained floating point is supported on this target. virtual bool hasStrictFP() const { return HasStrictFP; } + /// Determine whether vector int64 type is supported on this target. + virtual bool hasVectorInt64Support() const { return false; } + /// Determine whether vector half float (float16) type is supported on this /// target. virtual bool hasVectorFloat16Support() const { return false; } + /// Determine whether vector float32 type is supported on this target. + virtual bool hasVectorFloat32Support() const { return false; } + + /// Determine whether vector float32 type is supported on this target. + virtual bool hasVectorFloat64Support() const { return false; } + /// Return the alignment that is the largest alignment ever used for any /// scalar/SIMD data type on the target machine you are compiling for /// (including types with an extended alignment requirement). diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h --- a/clang/lib/Basic/Targets/RISCV.h +++ b/clang/lib/Basic/Targets/RISCV.h @@ -100,10 +100,16 @@ bool hasBitIntType() const override { return true; } + bool hasVectorInt64Support() const override { return hasFeature("zve64x"); } + bool hasVectorFloat16Support() const override { return hasFeature("experimental-zvfh"); } + bool hasVectorFloat32Support() const override { return hasFeature("zve32f"); } + + bool hasVectorFloat64Support() const override { return hasFeature("zve64d"); } + bool useFP16ConversionIntrinsics() const override { return false; } diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -2046,12 +2046,30 @@ targetDiag(D->getLocation(), diag::note_defined_here, FD) << D; } - if (Ty->isVectorFloat16Type() && - !Context.getTargetInfo().hasVectorFloat16Support()) { + if ((Ty->isVectorInt64Type() && + !Context.getTargetInfo().hasVectorInt64Support()) || + (Ty->isVectorFloat16Type() && + !Context.getTargetInfo().hasVectorFloat16Support()) || + (Ty->isVectorFloat32Type() && + !Context.getTargetInfo().hasVectorFloat32Support()) || + (Ty->isVectorFloat64Type() && + !Context.getTargetInfo().hasVectorFloat64Support())) { Diag(Loc, diag::err_require_vector_support) << Ty; + if (Ty->isVectorInt64Type() && Ty->isRVVInt64Type()) { + Diag(Loc, diag::err_riscv_type_requires_extension, FD) + << Ty << "zve64x"; + } if (Ty->isVectorFloat16Type() && Ty->isRVVFloat16Type()) { Diag(Loc, diag::err_riscv_type_requires_extension, FD) << Ty << "zvfh"; } + if (Ty->isVectorFloat32Type() && Ty->isRVVFloat32Type()) { + Diag(Loc, diag::err_riscv_type_requires_extension, FD) + << Ty << "zve32f"; + } + if (Ty->isVectorFloat64Type() && Ty->isRVVFloat64Type()) { + Diag(Loc, diag::err_riscv_type_requires_extension, FD) + << Ty << "zve64d"; + } } // Don't allow SVE types in functions without a SVE target. diff --git a/clang/lib/Sema/SemaRISCVVectorLookup.cpp b/clang/lib/Sema/SemaRISCVVectorLookup.cpp --- a/clang/lib/Sema/SemaRISCVVectorLookup.cpp +++ b/clang/lib/Sema/SemaRISCVVectorLookup.cpp @@ -169,8 +169,6 @@ void RISCVIntrinsicManagerImpl::InitIntrinsicList() { const TargetInfo &TI = Context.getTargetInfo(); - bool HasVectorFloat32 = TI.hasFeature("zve32f"); - bool HasVectorFloat64 = TI.hasFeature("zve64d"); bool HasRV64 = TI.hasFeature("64bit"); bool HasFullMultiply = TI.hasFeature("v"); @@ -222,12 +220,6 @@ continue; // Check requirement. - if (BaseType == BasicType::Float32 && !HasVectorFloat32) - continue; - - if (BaseType == BasicType::Float64 && !HasVectorFloat64) - continue; - if (((Record.RequiredExtensions & RVV_REQ_RV64) == RVV_REQ_RV64) && !HasRV64) continue; diff --git a/clang/test/Sema/riscv-vector-float32-check.c b/clang/test/Sema/riscv-vector-float32-check.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/riscv-vector-float32-check.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d \ +// RUN: -target-feature +zve32x -target-feature +zfh \ +// RUN: -disable-O0-optnone -o - -fsyntax-only %s -verify +// REQUIRES: riscv-registered-target +#include + +vfloat32m1_t foo() { /* expected-error {{Vector type 'vfloat32m1_t' (aka '__rvv_float32m1_t') is not supported in the current target}} */ /* expected-error {{RISC-V type 'vfloat32m1_t' (aka '__rvv_float32m1_t') requires the 'zve32f' extension}} */ +} /* expected-warning {{non-void function does not return a value}}*/ diff --git a/clang/test/Sema/riscv-vector-float64-check.c b/clang/test/Sema/riscv-vector-float64-check.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/riscv-vector-float64-check.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d \ +// RUN: -target-feature +zve64f -target-feature +zfh \ +// RUN: -disable-O0-optnone -o - -fsyntax-only %s -verify +// REQUIRES: riscv-registered-target +#include + +vfloat64m1_t foo() { /* expected-error {{Vector type 'vfloat64m1_t' (aka '__rvv_float64m1_t') is not supported in the current target}} */ /* expected-error {{RISC-V type 'vfloat64m1_t' (aka '__rvv_float64m1_t') requires the 'zve64d' extension}} */ +} /* expected-warning {{non-void function does not return a value}}*/ diff --git a/clang/test/Sema/riscv-vector-int64-check.c b/clang/test/Sema/riscv-vector-int64-check.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/riscv-vector-int64-check.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d \ +// RUN: -target-feature +zve32x -target-feature +zfh \ +// RUN: -disable-O0-optnone -o - -fsyntax-only %s -verify +// REQUIRES: riscv-registered-target +#include + +vint64m1_t foo() { /* expected-error {{Vector type 'vint64m1_t' (aka '__rvv_int64m1_t') is not supported in the current target}} */ /* expected-error {{RISC-V type 'vint64m1_t' (aka '__rvv_int64m1_t') requires the 'zve64x' extension}} */ +} /* expected-warning {{non-void function does not return a value}}*/ diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp --- a/clang/utils/TableGen/RISCVVEmitter.cpp +++ b/clang/utils/TableGen/RISCVVEmitter.cpp @@ -376,23 +376,19 @@ printType(*T); } - OS << "#if (__riscv_v_elen_fp >= 32)\n"; for (int Log2LMUL : Log2LMULs) { auto T = TypeCache.computeType(BasicType::Float32, Log2LMUL, PrototypeDescriptor::Vector); if (T) printType(*T); } - OS << "#endif\n"; - OS << "#if (__riscv_v_elen_fp >= 64)\n"; for (int Log2LMUL : Log2LMULs) { auto T = TypeCache.computeType(BasicType::Float64, Log2LMUL, PrototypeDescriptor::Vector); if (T) printType(*T); } - OS << "#endif\n\n"; OS << "#define __riscv_v_intrinsic_overloading 1\n";