diff --git a/clang/include/clang/Basic/riscv_vector.td b/clang/include/clang/Basic/riscv_vector.td index cf4dd8af2242d..7f0df6b729e29 100644 --- a/clang/include/clang/Basic/riscv_vector.td +++ b/clang/include/clang/Basic/riscv_vector.td @@ -2270,7 +2270,13 @@ let Log2LMUL = [-3, -2, -1, 0, 1, 2] in { def vfwcvt_rtz_x_f_v : RVVConvToWidenSignedBuiltin<"vfwcvt_rtz_x">; def vfwcvt_f_xu_v : RVVConvBuiltin<"Fw", "FwUv", "csi", "vfwcvt_f">; def vfwcvt_f_x_v : RVVConvBuiltin<"Fw", "Fwv", "csi", "vfwcvt_f">; - def vfwcvt_f_f_v : RVVConvBuiltin<"w", "wv", "xf", "vfwcvt_f">; + def vfwcvt_f_f_v : RVVConvBuiltin<"w", "wv", "f", "vfwcvt_f">; + let RequiredFeatures = ["ZvfhminOrZvfh"] in + def vfwcvt_f_f_v_fp16 : RVVConvBuiltin<"w", "wv", "x", "vfwcvt_f"> { + let Name = "vfwcvt_f_f_v"; + let IRName = "vfwcvt_f_f_v"; + let MaskedIRName = "vfwcvt_f_f_v_mask"; + } } // 14.19. Narrowing Floating-Point/Integer Type-Convert Instructions @@ -2360,9 +2366,11 @@ let ManualCodegen = [{ defm : RVVConvBuiltinSet<"vfncvt_f_xu_w", "csi", [["Fv", "FvUwu"]]>; } - let OverloadedName = "vfncvt_f" in - defm : - RVVConvBuiltinSet<"vfncvt_f_f_w", "xf", [["v", "vwu"]]>; + let OverloadedName = "vfncvt_f" in { + defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "f", [["v", "vwu"]]>; + let RequiredFeatures = ["ZvfhminOrZvfh"] in + defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "x", [["v", "vwu"]]>; + } } } @@ -2403,9 +2411,11 @@ let ManualCodegen = [{ defm : RVVConvBuiltinSet<"vfncvt_f_xu_w", "csi", [["Fv", "FvUw"]]>; } - let OverloadedName = "vfncvt_f" in - defm : - RVVConvBuiltinSet<"vfncvt_f_f_w", "xf", [["v", "vw"]]>; + let OverloadedName = "vfncvt_f" in { + defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "f", [["v", "vw"]]>; + let RequiredFeatures = ["ZvfhminOrZvfh"] in + defm : RVVConvBuiltinSet<"vfncvt_f_f_w", "x", [["v", "vw"]]>; + } } } } diff --git a/clang/include/clang/Support/RISCVVIntrinsicUtils.h b/clang/include/clang/Support/RISCVVIntrinsicUtils.h index f8a7e505a1e4e..72878368ce1a3 100644 --- a/clang/include/clang/Support/RISCVVIntrinsicUtils.h +++ b/clang/include/clang/Support/RISCVVIntrinsicUtils.h @@ -483,7 +483,8 @@ class RVVIntrinsic { enum RVVRequire : uint8_t { RVV_REQ_None = 0, RVV_REQ_RV64 = 1 << 0, - RVV_REQ_Xsfvcp = 1 << 1, + RVV_REQ_ZvfhminOrZvfh = 1 << 1, + RVV_REQ_Xsfvcp = 1 << 2, LLVM_MARK_AS_BITMASK_ENUM(RVV_REQ_Xsfvcp) }; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 660c0b55df892..e3b4d15153652 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5506,8 +5506,9 @@ void Sema::checkRVVTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) { !TI.hasFeature("zve64x")) Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve64x"; if (Ty->isRVVType(/* Bitwidth */ 16, /* IsFloat */ true) && - !TI.hasFeature("zvfh")) - Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zvfh"; + !TI.hasFeature("zvfh") && !TI.hasFeature("zvfhmin")) + Diag(Loc, diag::err_riscv_type_requires_extension, D) + << Ty << "zvfh or zvfhmin"; if (Ty->isRVVType(/* Bitwidth */ 32, /* IsFloat */ true) && !TI.hasFeature("zve32f")) Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32f"; diff --git a/clang/lib/Sema/SemaRISCVVectorLookup.cpp b/clang/lib/Sema/SemaRISCVVectorLookup.cpp index c5e076ffc70e5..ebdd498cc7644 100644 --- a/clang/lib/Sema/SemaRISCVVectorLookup.cpp +++ b/clang/lib/Sema/SemaRISCVVectorLookup.cpp @@ -262,6 +262,16 @@ void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics( if ((BaseTypeI & Record.TypeRangeMask) != BaseTypeI) continue; + if (BaseType == BasicType::Float16) { + if ((Record.RequiredExtensions & RVV_REQ_ZvfhminOrZvfh) == + RVV_REQ_ZvfhminOrZvfh) { + if (!TI.hasFeature("zvfh") && !TI.hasFeature("zvfhmin")) + continue; + } else if (!TI.hasFeature("zvfh")) { + continue; + } + } + // Expanded with different LMUL. for (int Log2LMUL = -3; Log2LMUL <= 3; Log2LMUL++) { if (!(Record.Log2LMULMask & (1 << (Log2LMUL + 3)))) diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/zvfhmin-error.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/zvfhmin-error.c new file mode 100644 index 0000000000000..d45ed77da6334 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/zvfhmin-error.c @@ -0,0 +1,24 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v \ +// RUN: -target-feature +zvfh -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-ZVF %s + +// RUN: not %clang_cc1 -triple riscv64 -target-feature +v \ +// RUN: -target-feature +zvfhmin -emit-llvm-only %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CHECK-ZVFHMIN-ERR + +#include + +// CHECK-ZVF-LABEL: @test_vfadd_vv_f16m1( +// CHECK-ZVF-NEXT: entry: +// CHECK-ZVF-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfadd.nxv4f16.nxv4f16.i64( poison, [[OP1:%.*]], [[OP2:%.*]], i64 [[VL:%.*]]) +// CHECK-ZVF-NEXT: ret [[TMP0]] +// + +// CHECK-ZVFHMIN-ERR: no matching function for call to '__riscv_vfadd' + +vfloat16m1_t test_vfadd_vv_f16m1(vfloat16m1_t op1, vfloat16m1_t op2, size_t vl) { + return __riscv_vfadd(op1, op2, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/zvfhmin.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/zvfhmin.c new file mode 100644 index 0000000000000..267a285de3072 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/zvfhmin.c @@ -0,0 +1,27 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v \ +// RUN: -target-feature +zvfhmin -disable-O0-optnone \ +// RUN: -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-ZVFHMIN %s + +#include + +// CHECK-ZVFHMIN-LABEL: @test_vfncvt_f_f_w_f16m1( +// CHECK-ZVFHMIN-NEXT: entry: +// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfncvt.f.f.w.nxv4f16.nxv4f32.i64( poison, [[SRC:%.*]], i64 [[VL:%.*]]) +// CHECK-ZVFHMIN-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_vfncvt_f_f_w_f16m1(vfloat32m2_t src, size_t vl) { + return __riscv_vfncvt_f(src, vl); +} + + +// CHECK-ZVFHMIN-LABEL: @test_vfwcvt_f_f_v_f16m1( +// CHECK-ZVFHMIN-NEXT: entry: +// CHECK-ZVFHMIN-NEXT: [[TMP0:%.*]] = call @llvm.riscv.vfwcvt.f.f.v.nxv4f32.nxv4f16.i64( poison, [[SRC:%.*]], i64 [[VL:%.*]]) +// CHECK-ZVFHMIN-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_vfwcvt_f_f_v_f16m1(vfloat16m1_t src, size_t vl) { + return __riscv_vfwcvt_f(src, vl); +} diff --git a/clang/test/Sema/riscv-vector-float16-check.c b/clang/test/Sema/riscv-vector-float16-check.c index e9fbe172725d8..6ec03c642adca 100644 --- a/clang/test/Sema/riscv-vector-float16-check.c +++ b/clang/test/Sema/riscv-vector-float16-check.c @@ -4,18 +4,18 @@ // REQUIRES: riscv-registered-target #include -vfloat16m1_t foo() { /* expected-error {{RISC-V type 'vfloat16m1_t' (aka '__rvv_float16m1_t') requires the 'zvfh' extension}} */ - vfloat16m1_t f16m1; /* expected-error {{RISC-V type 'vfloat16m1_t' (aka '__rvv_float16m1_t') requires the 'zvfh' extension}} */ +vfloat16m1_t foo() { /* expected-error {{RISC-V type 'vfloat16m1_t' (aka '__rvv_float16m1_t') requires the 'zvfh or zvfhmin' extension}} */ + vfloat16m1_t f16m1; /* expected-error {{RISC-V type 'vfloat16m1_t' (aka '__rvv_float16m1_t') requires the 'zvfh or zvfhmin' extension}} */ - (void)f16m1; /* expected-error {{RISC-V type 'vfloat16m1_t' (aka '__rvv_float16m1_t') requires the 'zvfh' extension}} */ + (void)f16m1; /* expected-error {{RISC-V type 'vfloat16m1_t' (aka '__rvv_float16m1_t') requires the 'zvfh or zvfhmin' extension}} */ - return f16m1; /* expected-error {{RISC-V type 'vfloat16m1_t' (aka '__rvv_float16m1_t') requires the 'zvfh' extension}} */ + return f16m1; /* expected-error {{RISC-V type 'vfloat16m1_t' (aka '__rvv_float16m1_t') requires the 'zvfh or zvfhmin' extension}} */ } -vfloat16m1x2_t bar() { /* expected-error {{RISC-V type 'vfloat16m1x2_t' (aka '__rvv_float16m1x2_t') requires the 'zvfh' extension}} */ - vfloat16m1x2_t f16m1x2; /* expected-error {{RISC-V type 'vfloat16m1x2_t' (aka '__rvv_float16m1x2_t') requires the 'zvfh' extension}} */ +vfloat16m1x2_t bar() { /* expected-error {{RISC-V type 'vfloat16m1x2_t' (aka '__rvv_float16m1x2_t') requires the 'zvfh or zvfhmin' extension}} */ + vfloat16m1x2_t f16m1x2; /* expected-error {{RISC-V type 'vfloat16m1x2_t' (aka '__rvv_float16m1x2_t') requires the 'zvfh or zvfhmin' extension}} */ - (void)f16m1x2; /* expected-error {{RISC-V type 'vfloat16m1x2_t' (aka '__rvv_float16m1x2_t') requires the 'zvfh' extension}} */ + (void)f16m1x2; /* expected-error {{RISC-V type 'vfloat16m1x2_t' (aka '__rvv_float16m1x2_t') requires the 'zvfh or zvfhmin' extension}} */ - return f16m1x2; /* expected-error {{RISC-V type 'vfloat16m1x2_t' (aka '__rvv_float16m1x2_t') requires the 'zvfh' extension}} */ + return f16m1x2; /* expected-error {{RISC-V type 'vfloat16m1x2_t' (aka '__rvv_float16m1x2_t') requires the 'zvfh or zvfhmin' extension}} */ } diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp index 9737aac95da25..8acd1d15649be 100644 --- a/clang/utils/TableGen/RISCVVEmitter.cpp +++ b/clang/utils/TableGen/RISCVVEmitter.cpp @@ -653,6 +653,7 @@ void RVVEmitter::createRVVIntrinsics( for (auto RequiredFeature : RequiredFeatures) { RVVRequire RequireExt = StringSwitch(RequiredFeature) .Case("RV64", RVV_REQ_RV64) + .Case("ZvfhminOrZvfh", RVV_REQ_ZvfhminOrZvfh) .Case("Xsfvcp", RVV_REQ_Xsfvcp) .Default(RVV_REQ_None); assert(RequireExt != RVV_REQ_None && "Unrecognized required feature?");