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,6 +2279,10 @@ bool isRVVType() const; + bool isVectorFloat16Type() const; + + bool isRVVFloat16Type() const; + /// Return the implicit lifetime for this type, which must not be dependent. Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; @@ -7160,6 +7164,24 @@ 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, ...) \ + isSpecificBuiltinType(BuiltinType::Id) || + return +#include "clang/Basic/RISCVVTypes.def" + false; // end of boolean or operation. +} + +inline bool Type::isRVVFloat16Type() const { +#define RVV_TYPE(Name, Id, SingletonId) false || +#define RVV_VECTOR_TYPE_HALF_FLOAT(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/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11738,6 +11738,9 @@ "builtin requires%select{| at least one of the following extensions to be enabled}0: %1">; def err_riscv_builtin_invalid_lmul : Error< "LMUL argument must be in the range [0,3] or [5,7]">; +def err_riscv_type_requires_extension : Error< + "RISC-V type %0 requires the '%1' extension" +>; def err_std_source_location_impl_not_found : Error< "'std::source_location::__impl' was not found; it must be defined before '__builtin_source_location' is called">; @@ -11798,4 +11801,9 @@ "%select{pointer|reference}0 to WebAssembly reference type is not allowed">; def err_wasm_ca_reference : Error< "cannot %select{capture|take address of}0 WebAssembly reference">; + +// Vector type support diagnostics. +def err_require_vector_support : Error < + "Vector type %0 is not supported in the current target" +>; } // end of sema component. 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,6 +60,10 @@ RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, false, true) #endif +#ifndef RVV_VECTOR_TYPE_HALF_FLOAT +#define RVV_VECTOR_TYPE_HALF_FLOAT RVV_VECTOR_TYPE_FLOAT +#endif + //===- Vector types -------------------------------------------------------===// RVV_VECTOR_TYPE_INT("__rvv_int8mf8_t", RvvInt8mf8, RvvInt8mf8Ty, 1, 8, 1, true) @@ -114,12 +118,12 @@ 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_FLOAT("__rvv_float16mf4_t",RvvFloat16mf4,RvvFloat16mf4Ty,1, 16, 1) -RVV_VECTOR_TYPE_FLOAT("__rvv_float16mf2_t",RvvFloat16mf2,RvvFloat16mf2Ty,2, 16, 1) -RVV_VECTOR_TYPE_FLOAT("__rvv_float16m1_t", RvvFloat16m1, RvvFloat16m1Ty, 4, 16, 1) -RVV_VECTOR_TYPE_FLOAT("__rvv_float16m2_t", RvvFloat16m2, RvvFloat16m2Ty, 8, 16, 1) -RVV_VECTOR_TYPE_FLOAT("__rvv_float16m4_t", RvvFloat16m4, RvvFloat16m4Ty, 16, 16, 1) -RVV_VECTOR_TYPE_FLOAT("__rvv_float16m8_t", RvvFloat16m8, RvvFloat16m8Ty, 32, 16, 1) +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) +RVV_VECTOR_TYPE_HALF_FLOAT("__rvv_float16m1_t", RvvFloat16m1, RvvFloat16m1Ty, 4, 16, 1) +RVV_VECTOR_TYPE_HALF_FLOAT("__rvv_float16m2_t", RvvFloat16m2, RvvFloat16m2Ty, 8, 16, 1) +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) @@ -141,6 +145,7 @@ RVV_PREDICATE_TYPE("__rvv_bool64_t", RvvBool64, RvvBool64Ty, 1) #undef RVV_VECTOR_TYPE_FLOAT +#undef RVV_VECTOR_TYPE_HALF_FLOAT #undef RVV_VECTOR_TYPE_INT #undef RVV_VECTOR_TYPE #undef RVV_PREDICATE_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,6 +664,10 @@ /// Determine whether constrained floating point is supported on this target. virtual bool hasStrictFP() const { return HasStrictFP; } + /// Determine whether vector half float (float16) type is supported on this + /// target. + virtual bool hasVectorFloat16Support() 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,6 +100,8 @@ bool hasBitIntType() const override { return true; } + bool hasVectorFloat16Support() const override { return hasFeature("zvfh"); } + 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,6 +2046,14 @@ targetDiag(D->getLocation(), diag::note_defined_here, FD) << D; } + if (Ty->isVectorFloat16Type() && + !Context.getTargetInfo().hasVectorFloat16Support()) { + Diag(Loc, diag::err_require_vector_support) << Ty; + if (Ty->isVectorFloat16Type() && Ty->isRVVFloat16Type()) { + Diag(Loc, diag::err_riscv_type_requires_extension, FD) << Ty << "zvfh"; + } + } + // Don't allow SVE types in functions without a SVE target. if (Ty->isSVESizelessBuiltinType() && FD && FD->hasBody()) { llvm::StringMap CallerFeatureMap; 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 @@ -171,7 +171,6 @@ const TargetInfo &TI = Context.getTargetInfo(); bool HasVectorFloat32 = TI.hasFeature("zve32f"); bool HasVectorFloat64 = TI.hasFeature("zve64d"); - bool HasZvfh = TI.hasFeature("experimental-zvfh"); bool HasRV64 = TI.hasFeature("64bit"); bool HasFullMultiply = TI.hasFeature("v"); @@ -223,9 +222,6 @@ continue; // Check requirement. - if (BaseType == BasicType::Float16 && !HasZvfh) - continue; - if (BaseType == BasicType::Float32 && !HasVectorFloat32) continue; diff --git a/clang/test/Sema/riscv-vector-float16-check.c b/clang/test/Sema/riscv-vector-float16-check.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/riscv-vector-float16-check.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d \ +// RUN: -target-feature +v -target-feature +zfh \ +// RUN: -disable-O0-optnone -o - -fsyntax-only %s -verify +// REQUIRES: riscv-registered-target +#include + +vfloat16m1_t foo() { /* expected-error {{Vector type 'vfloat16m1_t' (aka '__rvv_float16m1_t') is not supported in the current target}} */ /* expected-error {{RISC-V type 'vfloat16m1_t' (aka '__rvv_float16m1_t') requires the 'zvfh' 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 @@ -368,14 +368,13 @@ } } } - OS << "#if defined(__riscv_zvfh)\n"; + for (int Log2LMUL : Log2LMULs) { auto T = TypeCache.computeType(BasicType::Float16, Log2LMUL, PrototypeDescriptor::Vector); if (T) printType(*T); } - OS << "#endif\n"; OS << "#if (__riscv_v_elen_fp >= 32)\n"; for (int Log2LMUL : Log2LMULs) {