Add RVV intrinsics for the batched Zvbdota family[1]: Zvqwbdota8i, Zvqwbdota16i, Zvfwbdota16bf, Zvfqwbdota8f and Zvfbdota32f.
The intrinsic names follow the same pattern as Zvdota with the VS2 group type fixed at EMUL=8 and the VS1 source type at EMUL=1. The FP32 vfbdota form is a documented special case that uses only the destination type suffix. This commit also adds checking for the ci immediate (constant multiple of 8 in [0, 56]) and gates accumulator LMUL availability on sufficient VLEN. [1] https://github.com/riscv-non-isa/riscv-rvv-intrinsic-doc/commit/002d98e46e1fd65fedc88558b1695bb6c48dee37 gcc/ChangeLog: * config/riscv/riscv-vector-builtins-bases.cc (zvbdota_int_altfmt): Select ALTFMT from VS1 signedness. (zvbdota_fp8_altfmt): Select ALTFMT from VS1 FP8 format. (class vqwbdota): New expander. (class vfwbdota): Ditto. (class vfqwbdota): Ditto. (class vfbdota): Ditto. (BASE): Register vqwbdota, vfwbdota, vfqwbdota and vfbdota. * config/riscv/riscv-vector-builtins-bases.h: Declare new bases. * config/riscv/riscv-vector-builtins-functions.def: New def. * config/riscv/riscv-vector-builtins-shapes.cc (struct zvbdota_def): New shape with ci-immediate checking and vfbdota special casing. (SHAPE): Register zvbdota and zvbdota_frm. * config/riscv/riscv-vector-builtins-shapes.h: Declare them. * config/riscv/riscv-vector-builtins.cc (get_builtin_partition): Handle new Zvbdota partitions. (get_zvbdota_i8_type_index): New. (get_zvbdota_i16_type_index): New. (get_zvbdota_f32_type_index): New. (get_zvbdota_f32_group_type_index): New. (get_zvbdota_bf16_type_index): New. (get_zvbdota_fp8_type_index): New. (rvv_arg_type_info::get_function_type_index): Handle Zvbdota group and source base types. (function_expander::use_zvbdota_insn): New. (function_checker::require_zvbdota_ci): New. Validate ci immediate as a multiple of 8 in [0, 56]. (validate_instance_type_required_extensions): Gate Zvbdota accumulator LMUL on VLEN via RVV_REQUIRE_MIN_VLEN_* flags. * config/riscv/riscv-vector-builtins.def: New definitions. * config/riscv/riscv-vector-builtins.h (RVV_REQUIRE_MIN_VLEN_128): New definition. (RVV_REQUIRE_MIN_VLEN_256): Ditto. (RVV_REQUIRE_MIN_VLEN_512): Ditto. (enum required_ext): Add Zvbdota extensions. (enum rvv_builtin_partition): Ditto. (required_ext_to_isa_name): Handle them. (required_extensions_specified): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/zvbdota-acc-lmul-vlen32-fail.c: New test. * gcc.target/riscv/rvv/base/zvbdota-acc-lmul-vlen64-fail.c: New test. * gcc.target/riscv/rvv/base/zvbdota-ci-invalid.c: New test. * gcc.target/riscv/rvv/base/zvbdota-intrinsic.c: New test. * gcc.target/riscv/rvv/base/zvbdota-no-rm-fail.c: New test. --- .../riscv/riscv-vector-builtins-bases.cc | 91 ++++ .../riscv/riscv-vector-builtins-bases.h | 6 + .../riscv/riscv-vector-builtins-functions.def | 34 ++ .../riscv/riscv-vector-builtins-shapes.cc | 69 +++ .../riscv/riscv-vector-builtins-shapes.h | 2 + gcc/config/riscv/riscv-vector-builtins.cc | 505 ++++++++++++++++++ gcc/config/riscv/riscv-vector-builtins.def | 32 ++ gcc/config/riscv/riscv-vector-builtins.h | 35 ++ .../rvv/base/zvbdota-acc-lmul-vlen32-fail.c | 59 ++ .../rvv/base/zvbdota-acc-lmul-vlen64-fail.c | 35 ++ .../riscv/rvv/base/zvbdota-ci-invalid.c | 33 ++ .../riscv/rvv/base/zvbdota-intrinsic.c | 135 +++++ .../riscv/rvv/base/zvbdota-no-rm-fail.c | 25 + 13 files changed, 1061 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-acc-lmul-vlen32-fail.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-acc-lmul-vlen64-fail.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-ci-invalid.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-intrinsic.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-no-rm-fail.c diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index a41d0753422..06a83bbc6d1 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -2484,6 +2484,23 @@ zvdota_fp8_altfmt (const function_expander &e) : ALTFMT_NONE; } +static unsigned +zvbdota_int_altfmt (const function_expander &e) +{ + return (e.op_info->args[2].base_type == RVV_BASE_zvbdota_u8_src + || e.op_info->args[2].base_type == RVV_BASE_zvbdota_u16_src) + ? ALTFMT_NONE + : ALTFMT_ALT; +} + +static unsigned +zvbdota_fp8_altfmt (const function_expander &e) +{ + return e.op_info->args[2].base_type == RVV_BASE_zvbdota_f8e5m2_src + ? ALTFMT_ALT + : ALTFMT_NONE; +} + static bool zvdota_unsigned_vs2_p (vector_type_index type_idx) { @@ -2569,6 +2586,68 @@ public: } }; +class vqwbdota : public function_base +{ +public: + bool has_merge_operand_p () const override { return false; } + + rtx expand (function_expander &e) const override + { + bool vs2_unsigned_p + = (e.op_info->args[1].base_type == RVV_BASE_zvbdota_u8_group + || e.op_info->args[1].base_type == RVV_BASE_zvbdota_u16_group); + int unspec = vs2_unsigned_p ? UNSPEC_VQWBDOTAU : UNSPEC_VQWBDOTAS; + return e.use_zvbdota_insn ( + code_for_pred_vv (unspec, e.vector_mode ()), zvbdota_int_altfmt (e)); + } +}; + +class vfwbdota : public function_base +{ +public: + bool has_merge_operand_p () const override { return false; } + + rtx expand (function_expander &e) const override + { + return e.use_zvbdota_insn ( + code_for_pred_vfwbdota_vv (e.vector_mode ()), ALTFMT_ALT); + } +}; + +class vfqwbdota : public function_base +{ +public: + bool has_merge_operand_p () const override { return false; } + + rtx expand (function_expander &e) const override + { + int unspec = e.op_info->args[1].base_type == RVV_BASE_zvbdota_f8e5m2_group + ? UNSPEC_VFQWBDOTA_ALT + : UNSPEC_VFQWBDOTA; + return e.use_zvbdota_insn ( + code_for_pred_vv (unspec, e.vector_mode ()), zvbdota_fp8_altfmt (e)); + } +}; + +template<enum frm_op_type FRM_OP = NO_FRM> +class vfbdota : public function_base +{ +public: + bool has_merge_operand_p () const override { return false; } + + bool has_rounding_mode_operand_p () const override + { + return FRM_OP == HAS_FRM; + } + + bool may_require_frm_p () const override { return true; } + + rtx expand (function_expander &e) const override + { + return e.use_zvbdota_insn (code_for_pred_vfbdota_vv (e.vector_mode ())); + } +}; + static CONSTEXPR const vsetvl<false> vsetvl_obj; static CONSTEXPR const vsetvl<true> vsetvlmax_obj; static CONSTEXPR const loadstore<false, LST_UNIT_STRIDE, false> vle_obj; @@ -2897,6 +2976,12 @@ static CONSTEXPR const vfwmaccbf16<HAS_FRM> vfwmaccbf16_frm_obj; static CONSTEXPR const vqwdota vqwdota_obj; static CONSTEXPR const vfwdota vfwdota_obj; static CONSTEXPR const vfqwdota vfqwdota_obj; +/* Zvbdota. */ +static CONSTEXPR const vqwbdota vqwbdota_obj; +static CONSTEXPR const vfwbdota vfwbdota_obj; +static CONSTEXPR const vfqwbdota vfqwbdota_obj; +static CONSTEXPR const vfbdota<NO_FRM> vfbdota_obj; +static CONSTEXPR const vfbdota<HAS_FRM> vfbdota_frm_obj; /* Declare the function base NAME, pointing it to an instance of class <NAME>_obj. */ @@ -3229,4 +3314,10 @@ BASE (vfwmaccbf16_frm) BASE (vqwdota) BASE (vfwdota) BASE (vfqwdota) +/* Zvbdota */ +BASE (vqwbdota) +BASE (vfwbdota) +BASE (vfqwbdota) +BASE (vfbdota) +BASE (vfbdota_frm) } // end namespace riscv_vector diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h b/gcc/config/riscv/riscv-vector-builtins-bases.h index f561c632a9c..24e9e066539 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.h +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h @@ -356,6 +356,12 @@ extern const function_base *const vfwmaccbf16_frm; extern const function_base *const vqwdota; extern const function_base *const vfwdota; extern const function_base *const vfqwdota; +/* Zvbdota */ +extern const function_base *const vqwbdota; +extern const function_base *const vfwbdota; +extern const function_base *const vfqwbdota; +extern const function_base *const vfbdota; +extern const function_base *const vfbdota_frm; } } // end namespace riscv_vector diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def b/gcc/config/riscv/riscv-vector-builtins-functions.def index 0d037937cad..ba3ee496f11 100644 --- a/gcc/config/riscv/riscv-vector-builtins-functions.def +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def @@ -460,6 +460,40 @@ DEF_RVV_FUNCTION (vfqwdota, zvdota, no_mu_preds, DEF_RVV_FUNCTION (vfqwdota, zvdota, no_mu_preds, zvfqwdota8f_e5m2_e5m2_vv_ops) +#undef REQUIRED_EXTENSIONS +#define REQUIRED_EXTENSIONS ZVQWBDOTA8I_EXT +DEF_RVV_FUNCTION (vqwbdota, zvbdota, full_preds, zvqwbdota8i_ss_vv_ops) +DEF_RVV_FUNCTION (vqwbdota, zvbdota, full_preds, zvqwbdota8i_su_vv_ops) +DEF_RVV_FUNCTION (vqwbdota, zvbdota, full_preds, zvqwbdota8i_us_vv_ops) +DEF_RVV_FUNCTION (vqwbdota, zvbdota, full_preds, zvqwbdota8i_uu_vv_ops) + +#undef REQUIRED_EXTENSIONS +#define REQUIRED_EXTENSIONS ZVQWBDOTA16I_EXT +DEF_RVV_FUNCTION (vqwbdota, zvbdota, full_preds, zvqwbdota16i_ss_vv_ops) +DEF_RVV_FUNCTION (vqwbdota, zvbdota, full_preds, zvqwbdota16i_su_vv_ops) +DEF_RVV_FUNCTION (vqwbdota, zvbdota, full_preds, zvqwbdota16i_us_vv_ops) +DEF_RVV_FUNCTION (vqwbdota, zvbdota, full_preds, zvqwbdota16i_uu_vv_ops) + +#undef REQUIRED_EXTENSIONS +#define REQUIRED_EXTENSIONS ZVFWBDOTA16BF_EXT +DEF_RVV_FUNCTION (vfwbdota, zvbdota, full_preds, zvfwbdota16bf_vv_ops) + +#undef REQUIRED_EXTENSIONS +#define REQUIRED_EXTENSIONS ZVFQWBDOTA8F_EXT +DEF_RVV_FUNCTION (vfqwbdota, zvbdota, full_preds, + zvfqwbdota8f_e4m3_e4m3_vv_ops) +DEF_RVV_FUNCTION (vfqwbdota, zvbdota, full_preds, + zvfqwbdota8f_e4m3_e5m2_vv_ops) +DEF_RVV_FUNCTION (vfqwbdota, zvbdota, full_preds, + zvfqwbdota8f_e5m2_e4m3_vv_ops) +DEF_RVV_FUNCTION (vfqwbdota, zvbdota, full_preds, + zvfqwbdota8f_e5m2_e5m2_vv_ops) + +#undef REQUIRED_EXTENSIONS +#define REQUIRED_EXTENSIONS ZVFBDOTA32F_EXT +DEF_RVV_FUNCTION (vfbdota, zvbdota, full_preds, zvfbdota32f_vv_ops) +DEF_RVV_FUNCTION (vfbdota_frm, zvbdota_frm, full_preds, zvfbdota32f_vv_ops) + #undef REQUIRED_EXTENSIONS #define REQUIRED_EXTENSIONS VECTOR_EXT diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc index dce48bef42e..2d8f1f081a7 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc @@ -462,6 +462,73 @@ struct zvdota_def : public build_base } }; +/* zvbdota_def class. */ +struct zvbdota_def : public build_base +{ + char *get_name (function_builder &b, const function_instance &instance, + bool overloaded_p) const override + { + char base_name[BASE_NAME_MAX_LEN] = {}; + + /* Return nullptr if it can not be overloaded. */ + if (overloaded_p && !instance.base->can_be_overloaded_p (instance.pred)) + return nullptr; + + strncpy (base_name, instance.base_name, sizeof (base_name) - 1); + char *frm_suffix = strstr (base_name, "_frm"); + if (frm_suffix) + *frm_suffix = '\0'; + + b.append_base_name (base_name); + + if (!overloaded_p) + { + vector_type_index ret_type_idx + = instance.op_info->ret.get_function_type_index ( + instance.type.index); + + b.append_name (operand_suffixes[instance.op_info->op]); + if (strcmp (base_name, "vfbdota") != 0) + { + vector_type_index vs2_type_idx + = instance.op_info->args[1].get_function_type_index ( + instance.type.index); + vector_type_index vs1_type_idx + = instance.op_info->args[2].get_function_type_index ( + instance.type.index); + + b.append_name (type_suffixes[vs2_type_idx].vector); + b.append_name (type_suffixes[vs1_type_idx].vector); + } + b.append_name (type_suffixes[ret_type_idx].vector); + + if (frm_suffix) + b.append_name ("_rm"); + } + + if (overloaded_p && instance.pred == PRED_TYPE_m) + return b.finish_name (); + b.append_name (predication_suffixes[instance.pred]); + return b.finish_name (); + } + + bool check (function_checker &c) const override + { + bool ok = true; + unsigned int ci_argno + = c.arg_num () - (c.base->has_rounding_mode_operand_p () ? 3 : 2); + + if (ci_argno < c.arg_num ()) + ok &= c.require_zvbdota_ci (ci_argno); + + if (c.base->has_rounding_mode_operand_p () && c.arg_num () >= 2) + ok &= c.require_immediate (c.arg_num () - 2, FRM_STATIC_MIN, + FRM_STATIC_MAX); + + return ok; + } +}; + /* The base class for frm build. */ struct build_frm_base : public build_base { @@ -1466,6 +1533,8 @@ SHAPE(crypto_vv, crypto_vv) SHAPE(crypto_vi, crypto_vi) SHAPE(crypto_vv_no_op_type, crypto_vv_no_op_type) SHAPE(zvdota, zvdota) +SHAPE(zvbdota, zvbdota) +SHAPE(zvbdota, zvbdota_frm) SHAPE (sf_vqmacc, sf_vqmacc) SHAPE (sf_vfnrclip, sf_vfnrclip) SHAPE(sf_vcix_se, sf_vcix_se) diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.h b/gcc/config/riscv/riscv-vector-builtins-shapes.h index db3c645fb37..f1ae2239650 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.h +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h @@ -33,6 +33,8 @@ extern const function_shape *const th_indexed_loadstore_width; extern const function_shape *const alu; extern const function_shape *const alu_frm; extern const function_shape *const zvdota; +extern const function_shape *const zvbdota; +extern const function_shape *const zvbdota_frm; extern const function_shape *const widen_alu; extern const function_shape *const widen_alu_frm; extern const function_shape *const no_mask_policy; diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 4894c0183b3..c0594235ee9 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -658,6 +658,68 @@ static const rvv_type_info zvfqwdota8f_e5m2_ops[] = { {VECTOR_TYPE_vfloat8e5m2m8_t, 0}, {NUM_VECTOR_TYPES, 0}}; +static const rvv_type_info zvqwbdota8i_i_ops[] = { + {VECTOR_TYPE_vint32m1_t, RVV_REQUIRE_MIN_VLEN_256}, + {VECTOR_TYPE_vint32m2_t, RVV_REQUIRE_MIN_VLEN_128}, + {VECTOR_TYPE_vint32m4_t, RVV_REQUIRE_MIN_VLEN_64}, + {VECTOR_TYPE_vint32m8_t, 0}, + {NUM_VECTOR_TYPES, 0}}; + +static const rvv_type_info zvqwbdota8i_u_ops[] = { + {VECTOR_TYPE_vuint32m1_t, RVV_REQUIRE_MIN_VLEN_256}, + {VECTOR_TYPE_vuint32m2_t, RVV_REQUIRE_MIN_VLEN_128}, + {VECTOR_TYPE_vuint32m4_t, RVV_REQUIRE_MIN_VLEN_64}, + {VECTOR_TYPE_vuint32m8_t, 0}, + {NUM_VECTOR_TYPES, 0}}; + +static const rvv_type_info zvqwbdota16i_i_ops[] = { + {VECTOR_TYPE_vint64m1_t, RVV_REQUIRE_ELEN_64 | RVV_REQUIRE_MIN_VLEN_512}, + {VECTOR_TYPE_vint64m2_t, RVV_REQUIRE_ELEN_64 | RVV_REQUIRE_MIN_VLEN_256}, + {VECTOR_TYPE_vint64m4_t, RVV_REQUIRE_ELEN_64 | RVV_REQUIRE_MIN_VLEN_128}, + {VECTOR_TYPE_vint64m8_t, RVV_REQUIRE_ELEN_64 | RVV_REQUIRE_MIN_VLEN_64}, + {NUM_VECTOR_TYPES, 0}}; + +static const rvv_type_info zvqwbdota16i_u_ops[] = { + {VECTOR_TYPE_vuint64m1_t, RVV_REQUIRE_ELEN_64 | RVV_REQUIRE_MIN_VLEN_512}, + {VECTOR_TYPE_vuint64m2_t, RVV_REQUIRE_ELEN_64 | RVV_REQUIRE_MIN_VLEN_256}, + {VECTOR_TYPE_vuint64m4_t, RVV_REQUIRE_ELEN_64 | RVV_REQUIRE_MIN_VLEN_128}, + {VECTOR_TYPE_vuint64m8_t, RVV_REQUIRE_ELEN_64 | RVV_REQUIRE_MIN_VLEN_64}, + {NUM_VECTOR_TYPES, 0}}; + +static const rvv_type_info zvfwbdota16bf_ops[] = { + {VECTOR_TYPE_vfloat32m1_t, + RVV_REQUIRE_ELEN_BF_16 | RVV_REQUIRE_ELEN_FP_32 + | RVV_REQUIRE_MIN_VLEN_256}, + {VECTOR_TYPE_vfloat32m2_t, + RVV_REQUIRE_ELEN_BF_16 | RVV_REQUIRE_ELEN_FP_32 + | RVV_REQUIRE_MIN_VLEN_128}, + {VECTOR_TYPE_vfloat32m4_t, + RVV_REQUIRE_ELEN_BF_16 | RVV_REQUIRE_ELEN_FP_32 + | RVV_REQUIRE_MIN_VLEN_64}, + {VECTOR_TYPE_vfloat32m8_t, + RVV_REQUIRE_ELEN_BF_16 | RVV_REQUIRE_ELEN_FP_32}, + {NUM_VECTOR_TYPES, 0}}; + +static const rvv_type_info zvfqwbdota8f_ops[] = { + {VECTOR_TYPE_vfloat32m1_t, + RVV_REQUIRE_ELEN_FP_32 | RVV_REQUIRE_MIN_VLEN_256}, + {VECTOR_TYPE_vfloat32m2_t, + RVV_REQUIRE_ELEN_FP_32 | RVV_REQUIRE_MIN_VLEN_128}, + {VECTOR_TYPE_vfloat32m4_t, + RVV_REQUIRE_ELEN_FP_32 | RVV_REQUIRE_MIN_VLEN_64}, + {VECTOR_TYPE_vfloat32m8_t, RVV_REQUIRE_ELEN_FP_32}, + {NUM_VECTOR_TYPES, 0}}; + +static const rvv_type_info zvfbdota32f_ops[] = { + {VECTOR_TYPE_vfloat32m1_t, + RVV_REQUIRE_ELEN_FP_32 | RVV_REQUIRE_MIN_VLEN_256}, + {VECTOR_TYPE_vfloat32m2_t, + RVV_REQUIRE_ELEN_FP_32 | RVV_REQUIRE_MIN_VLEN_128}, + {VECTOR_TYPE_vfloat32m4_t, + RVV_REQUIRE_ELEN_FP_32 | RVV_REQUIRE_MIN_VLEN_64}, + {VECTOR_TYPE_vfloat32m8_t, RVV_REQUIRE_ELEN_FP_32}, + {NUM_VECTOR_TYPES, 0}}; + static CONSTEXPR const rvv_arg_type_info rvv_arg_type_info_end = rvv_arg_type_info (NUM_BASE_TYPES); @@ -792,6 +854,90 @@ static CONSTEXPR const rvv_arg_type_info zvdota_fp8_e5m2_args[] rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_fp8e5m2_vector), rvv_arg_type_info_end}; +static CONSTEXPR const rvv_arg_type_info zvbdota_i8_ss_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_zvbdota_i8_group), + rvv_arg_type_info (RVV_BASE_zvbdota_i8_src), + rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; + +static CONSTEXPR const rvv_arg_type_info zvbdota_i8_su_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_zvbdota_i8_group), + rvv_arg_type_info (RVV_BASE_zvbdota_u8_src), + rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; + +static CONSTEXPR const rvv_arg_type_info zvbdota_i8_us_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_zvbdota_u8_group), + rvv_arg_type_info (RVV_BASE_zvbdota_i8_src), + rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; + +static CONSTEXPR const rvv_arg_type_info zvbdota_i8_uu_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_zvbdota_u8_group), + rvv_arg_type_info (RVV_BASE_zvbdota_u8_src), + rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; + +static CONSTEXPR const rvv_arg_type_info zvbdota_i16_ss_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_zvbdota_i16_group), + rvv_arg_type_info (RVV_BASE_zvbdota_i16_src), + rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; + +static CONSTEXPR const rvv_arg_type_info zvbdota_i16_su_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_zvbdota_i16_group), + rvv_arg_type_info (RVV_BASE_zvbdota_u16_src), + rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; + +static CONSTEXPR const rvv_arg_type_info zvbdota_i16_us_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_zvbdota_u16_group), + rvv_arg_type_info (RVV_BASE_zvbdota_i16_src), + rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; + +static CONSTEXPR const rvv_arg_type_info zvbdota_i16_uu_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_zvbdota_u16_group), + rvv_arg_type_info (RVV_BASE_zvbdota_u16_src), + rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; + +static CONSTEXPR const rvv_arg_type_info zvbdota_bf16_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_zvbdota_bf16_group), + rvv_arg_type_info (RVV_BASE_zvbdota_bf16_src), + rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; + +static CONSTEXPR const rvv_arg_type_info zvbdota_fp8_e4m3_e4m3_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_zvbdota_f8e4m3_group), + rvv_arg_type_info (RVV_BASE_zvbdota_f8e4m3_src), + rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; + +static CONSTEXPR const rvv_arg_type_info zvbdota_fp8_e4m3_e5m2_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_zvbdota_f8e4m3_group), + rvv_arg_type_info (RVV_BASE_zvbdota_f8e5m2_src), + rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; + +static CONSTEXPR const rvv_arg_type_info zvbdota_fp8_e5m2_e4m3_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_zvbdota_f8e5m2_group), + rvv_arg_type_info (RVV_BASE_zvbdota_f8e4m3_src), + rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; + +static CONSTEXPR const rvv_arg_type_info zvbdota_fp8_e5m2_e5m2_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_zvbdota_f8e5m2_group), + rvv_arg_type_info (RVV_BASE_zvbdota_f8e5m2_src), + rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; + +static CONSTEXPR const rvv_arg_type_info zvbdota_f32_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_zvbdota_f32_group), + rvv_arg_type_info (RVV_BASE_zvbdota_f32_src), + rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; + /* A list of args for vector_type func (vector_type, vector_type, vector_type) * function. */ static CONSTEXPR const rvv_arg_type_info vvv_args[] @@ -1711,6 +1857,90 @@ static CONSTEXPR const rvv_op_info zvfqwdota8f_e5m2_e5m2_vv_ops rvv_arg_type_info (RVV_BASE_zvdota_f32_acc), /* Return type */ zvdota_fp8_e5m2_args /* Args */}; +static CONSTEXPR const rvv_op_info zvqwbdota8i_ss_vv_ops + = {zvqwbdota8i_i_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + zvbdota_i8_ss_args /* Args */}; + +static CONSTEXPR const rvv_op_info zvqwbdota8i_su_vv_ops + = {zvqwbdota8i_i_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + zvbdota_i8_su_args /* Args */}; + +static CONSTEXPR const rvv_op_info zvqwbdota8i_us_vv_ops + = {zvqwbdota8i_i_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + zvbdota_i8_us_args /* Args */}; + +static CONSTEXPR const rvv_op_info zvqwbdota8i_uu_vv_ops + = {zvqwbdota8i_u_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + zvbdota_i8_uu_args /* Args */}; + +static CONSTEXPR const rvv_op_info zvqwbdota16i_ss_vv_ops + = {zvqwbdota16i_i_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + zvbdota_i16_ss_args /* Args */}; + +static CONSTEXPR const rvv_op_info zvqwbdota16i_su_vv_ops + = {zvqwbdota16i_i_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + zvbdota_i16_su_args /* Args */}; + +static CONSTEXPR const rvv_op_info zvqwbdota16i_us_vv_ops + = {zvqwbdota16i_i_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + zvbdota_i16_us_args /* Args */}; + +static CONSTEXPR const rvv_op_info zvqwbdota16i_uu_vv_ops + = {zvqwbdota16i_u_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + zvbdota_i16_uu_args /* Args */}; + +static CONSTEXPR const rvv_op_info zvfwbdota16bf_vv_ops + = {zvfwbdota16bf_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + zvbdota_bf16_args /* Args */}; + +static CONSTEXPR const rvv_op_info zvfqwbdota8f_e4m3_e4m3_vv_ops + = {zvfqwbdota8f_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + zvbdota_fp8_e4m3_e4m3_args /* Args */}; + +static CONSTEXPR const rvv_op_info zvfqwbdota8f_e4m3_e5m2_vv_ops + = {zvfqwbdota8f_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + zvbdota_fp8_e4m3_e5m2_args /* Args */}; + +static CONSTEXPR const rvv_op_info zvfqwbdota8f_e5m2_e4m3_vv_ops + = {zvfqwbdota8f_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + zvbdota_fp8_e5m2_e4m3_args /* Args */}; + +static CONSTEXPR const rvv_op_info zvfqwbdota8f_e5m2_e5m2_vv_ops + = {zvfqwbdota8f_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + zvbdota_fp8_e5m2_e5m2_args /* Args */}; + +static CONSTEXPR const rvv_op_info zvfbdota32f_vv_ops + = {zvfbdota32f_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + zvbdota_f32_args /* Args */}; + /* A static operand information for vector_type func (vector_type, scalar_type, * vector_type) function registration. */ static CONSTEXPR const rvv_op_info f_vvfv_ops @@ -3850,6 +4080,16 @@ get_builtin_partition (required_ext ext, const function_instance &instance) return RVV_PARTITION_ZVFWDOTA16BF; case ZVFQWDOTA8F_EXT: return RVV_PARTITION_ZVFQWDOTA8F; + case ZVQWBDOTA8I_EXT: + return RVV_PARTITION_ZVQWBDOTA8I; + case ZVQWBDOTA16I_EXT: + return RVV_PARTITION_ZVQWBDOTA16I; + case ZVFWBDOTA16BF_EXT: + return RVV_PARTITION_ZVFWBDOTA16BF; + case ZVFQWBDOTA8F_EXT: + return RVV_PARTITION_ZVFQWBDOTA8F; + case ZVFBDOTA32F_EXT: + return RVV_PARTITION_ZVFBDOTA32F; case XSFVQMACCQOQ_EXT: return RVV_PARTITION_XSFVQMACCQOQ; case XSFVQMACCDOD_EXT: @@ -4490,6 +4730,121 @@ get_float8_type_index (vector_type_index type_idx, bool e5m2_p) } } +static vector_type_index +get_zvbdota_i8_type_index (vector_type_index type_idx, bool unsigned_p, + bool group_p) +{ + switch (type_idx) + { + case VECTOR_TYPE_vint32m1_t: + case VECTOR_TYPE_vuint32m1_t: + case VECTOR_TYPE_vint32m2_t: + case VECTOR_TYPE_vuint32m2_t: + case VECTOR_TYPE_vint32m4_t: + case VECTOR_TYPE_vuint32m4_t: + case VECTOR_TYPE_vint32m8_t: + case VECTOR_TYPE_vuint32m8_t: + if (unsigned_p) + return group_p ? VECTOR_TYPE_vuint8m8_t : VECTOR_TYPE_vuint8m1_t; + return group_p ? VECTOR_TYPE_vint8m8_t : VECTOR_TYPE_vint8m1_t; + + default: + return VECTOR_TYPE_INVALID; + } +} + +static vector_type_index +get_zvbdota_i16_type_index (vector_type_index type_idx, bool unsigned_p, + bool group_p) +{ + switch (type_idx) + { + case VECTOR_TYPE_vint64m1_t: + case VECTOR_TYPE_vuint64m1_t: + case VECTOR_TYPE_vint64m2_t: + case VECTOR_TYPE_vuint64m2_t: + case VECTOR_TYPE_vint64m4_t: + case VECTOR_TYPE_vuint64m4_t: + case VECTOR_TYPE_vint64m8_t: + case VECTOR_TYPE_vuint64m8_t: + if (unsigned_p) + return group_p ? VECTOR_TYPE_vuint16m8_t : VECTOR_TYPE_vuint16m1_t; + return group_p ? VECTOR_TYPE_vint16m8_t : VECTOR_TYPE_vint16m1_t; + + default: + return VECTOR_TYPE_INVALID; + } +} + +static vector_type_index +get_zvbdota_f32_type_index (vector_type_index type_idx) +{ + switch (type_idx) + { + case VECTOR_TYPE_vfloat32m1_t: + case VECTOR_TYPE_vfloat32m2_t: + case VECTOR_TYPE_vfloat32m4_t: + case VECTOR_TYPE_vfloat32m8_t: + return VECTOR_TYPE_vfloat32m1_t; + + default: + return VECTOR_TYPE_INVALID; + } +} + +static vector_type_index +get_zvbdota_f32_group_type_index (vector_type_index type_idx) +{ + switch (type_idx) + { + case VECTOR_TYPE_vfloat32m1_t: + case VECTOR_TYPE_vfloat32m2_t: + case VECTOR_TYPE_vfloat32m4_t: + case VECTOR_TYPE_vfloat32m8_t: + return VECTOR_TYPE_vfloat32m8_t; + + default: + return VECTOR_TYPE_INVALID; + } +} + +static vector_type_index +get_zvbdota_bf16_type_index (vector_type_index type_idx, bool group_p) +{ + switch (type_idx) + { + case VECTOR_TYPE_vfloat32m1_t: + case VECTOR_TYPE_vfloat32m2_t: + case VECTOR_TYPE_vfloat32m4_t: + case VECTOR_TYPE_vfloat32m8_t: + return group_p ? VECTOR_TYPE_vbfloat16m8_t : VECTOR_TYPE_vbfloat16m1_t; + + default: + return VECTOR_TYPE_INVALID; + } +} + +static vector_type_index +get_zvbdota_fp8_type_index (vector_type_index type_idx, bool e5m2_p, + bool group_p) +{ + switch (type_idx) + { + case VECTOR_TYPE_vfloat32m1_t: + case VECTOR_TYPE_vfloat32m2_t: + case VECTOR_TYPE_vfloat32m4_t: + case VECTOR_TYPE_vfloat32m8_t: + if (e5m2_p) + return group_p ? VECTOR_TYPE_vfloat8e5m2m8_t + : VECTOR_TYPE_vfloat8e5m2m1_t; + return group_p ? VECTOR_TYPE_vfloat8e4m3m8_t + : VECTOR_TYPE_vfloat8e4m3m1_t; + + default: + return VECTOR_TYPE_INVALID; + } +} + vector_type_index rvv_arg_type_info::get_function_type_index (vector_type_index type_idx) const { @@ -4511,10 +4866,63 @@ rvv_arg_type_info::get_function_type_index (vector_type_index type_idx) const case RVV_BASE_fp8e5m2_vector: function_type_idx = get_float8_type_index (type_idx, true); break; + case RVV_BASE_zvbdota_i8_group: + function_type_idx = get_zvbdota_i8_type_index (type_idx, false, true); + break; + case RVV_BASE_zvbdota_u8_group: + function_type_idx = get_zvbdota_i8_type_index (type_idx, true, true); + break; + case RVV_BASE_zvbdota_i8_src: + function_type_idx = get_zvbdota_i8_type_index (type_idx, false, false); + break; + case RVV_BASE_zvbdota_u8_src: + function_type_idx = get_zvbdota_i8_type_index (type_idx, true, false); + break; + case RVV_BASE_zvbdota_i16_group: + function_type_idx = get_zvbdota_i16_type_index (type_idx, false, true); + break; + case RVV_BASE_zvbdota_u16_group: + function_type_idx = get_zvbdota_i16_type_index (type_idx, true, true); + break; + case RVV_BASE_zvbdota_i16_src: + function_type_idx = get_zvbdota_i16_type_index (type_idx, false, false); + break; + case RVV_BASE_zvbdota_u16_src: + function_type_idx = get_zvbdota_i16_type_index (type_idx, true, false); + break; + case RVV_BASE_zvbdota_bf16_group: + function_type_idx = get_zvbdota_bf16_type_index (type_idx, true); + break; + case RVV_BASE_zvbdota_bf16_src: + function_type_idx = get_zvbdota_bf16_type_index (type_idx, false); + break; + case RVV_BASE_zvbdota_f8e4m3_group: + function_type_idx = get_zvbdota_fp8_type_index (type_idx, false, true); + break; + case RVV_BASE_zvbdota_f8e4m3_src: + function_type_idx = get_zvbdota_fp8_type_index (type_idx, false, false); + break; + case RVV_BASE_zvbdota_f8e5m2_group: + function_type_idx = get_zvbdota_fp8_type_index (type_idx, true, true); + break; + case RVV_BASE_zvbdota_f8e5m2_src: + function_type_idx = get_zvbdota_fp8_type_index (type_idx, true, false); + break; + case RVV_BASE_zvbdota_f32_group: + function_type_idx = get_zvbdota_f32_group_type_index (type_idx); + break; + case RVV_BASE_zvbdota_f32_src: + function_type_idx = get_zvbdota_f32_type_index (type_idx); + break; default: break; } + if (function_type_idx == VECTOR_TYPE_INVALID + && base_type >= RVV_BASE_zvbdota_i8_group + && base_type <= RVV_BASE_zvbdota_f32_src) + return NUM_VECTOR_TYPES; + if (function_type_idx != VECTOR_TYPE_INVALID) return builtin_types[function_type_idx].vector ? function_type_idx : NUM_VECTOR_TYPES; @@ -5421,6 +5829,45 @@ function_expander::use_zvdota_insn (insn_code icode, unsigned altfmt) return generate_insn (icode); } +/* Implement Zvbdota destructive-accumulator calls. The machine patterns use + the source vector mode to control vsetvl, tie the accumulator input to the + output register, and take ci before the VL operand. */ +rtx +function_expander::use_zvbdota_insn (insn_code icode, unsigned altfmt) +{ + int arg_offset = 0; + + if (use_real_mask_p (pred)) + add_input_operand (arg_offset++); + else + add_all_one_mask_operand (mask_mode ()); + + add_input_operand (arg_offset++); + add_input_operand (arg_offset++); + add_input_operand (arg_offset++); + add_input_operand (arg_offset++); + add_input_operand (call_expr_nargs (exp) - 1); + + add_input_operand (Pmode, get_tail_policy_for_pred (pred)); + add_input_operand (Pmode, get_mask_policy_for_pred (pred)); + add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX)); + + if (altfmt != RVV_NO_ALTFMT + && opno < insn_data[icode].n_generator_args) + add_input_operand (Pmode, gen_int_mode (altfmt, Pmode)); + + if (base->has_rounding_mode_operand_p ()) + add_input_operand (call_expr_nargs (exp) - 2); + + /* The RVV floating-point only support dynamic rounding mode in the + FRM register. */ + if (base->may_require_frm_p () + && opno < insn_data[icode].n_generator_args) + add_input_operand (Pmode, gen_int_mode (riscv_vector::FRM_DYN, Pmode)); + + return generate_insn (icode); +} + /* Implement the call using instruction ICODE, with a 1:1 mapping between arguments and input operands. There are operands that cannot be broadcast using v[f]mv. In that case @@ -5654,6 +6101,32 @@ function_checker::require_immediate_range_or (unsigned int argno, return true; } +/* Check that argument ARGNO is a valid Zvbdota ci immediate. */ +bool +function_checker::require_zvbdota_ci (unsigned int argno) const +{ + gcc_assert (argno < m_nargs); + + tree arg = m_args[argno]; + if (TREE_CODE (arg) != INTEGER_CST) + { + report_non_ice (argno); + return false; + } + + widest_int actual = wi::to_widest (arg); + if (actual < 0 || actual > 56 || actual.to_shwi () % 8 != 0) + { + error_at (location, + "argument %d of %qE must be a constant multiple of 8 in the " + "range [0, 56]", + argno + 1, fndecl); + return false; + } + + return true; +} + /* Perform semantic checks on the call. Return true if the call is valid, otherwise report a suitable error. */ bool @@ -6047,6 +6520,38 @@ validate_instance_type_required_extensions (const rvv_type_info type, return false; } + if ((exts & RVV_REQUIRE_MIN_VLEN_64) && TARGET_MIN_VLEN < 64) + { + error_at (EXPR_LOCATION (exp), + "built-in function %qE requires the zvl64b ISA extension", + exp); + return false; + } + + if ((exts & RVV_REQUIRE_MIN_VLEN_128) && TARGET_MIN_VLEN < 128) + { + error_at (EXPR_LOCATION (exp), + "built-in function %qE requires the zvl128b ISA extension", + exp); + return false; + } + + if ((exts & RVV_REQUIRE_MIN_VLEN_256) && TARGET_MIN_VLEN < 256) + { + error_at (EXPR_LOCATION (exp), + "built-in function %qE requires the zvl256b ISA extension", + exp); + return false; + } + + if ((exts & RVV_REQUIRE_MIN_VLEN_512) && TARGET_MIN_VLEN < 512) + { + error_at (EXPR_LOCATION (exp), + "built-in function %qE requires the zvl512b ISA extension", + exp); + return false; + } + return true; } diff --git a/gcc/config/riscv/riscv-vector-builtins.def b/gcc/config/riscv/riscv-vector-builtins.def index eeade4e8e66..8a838ac3abd 100644 --- a/gcc/config/riscv/riscv-vector-builtins.def +++ b/gcc/config/riscv/riscv-vector-builtins.def @@ -787,6 +787,38 @@ DEF_RVV_BASE_TYPE (vlmul_ext_x64, get_vector_type (type_idx)) DEF_RVV_BASE_TYPE (zvdota_acc, get_vector_type (type_idx)) DEF_RVV_BASE_TYPE (zvdota_uacc, get_vector_type (type_idx)) DEF_RVV_BASE_TYPE (zvdota_f32_acc, get_vector_type (type_idx)) +DEF_RVV_BASE_TYPE (zvbdota_i8_group, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_u8_group, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_i8_src, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_u8_src, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_i16_group, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_u16_group, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_i16_src, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_u16_src, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_bf16_group, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_bf16_src, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_f8e4m3_group, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_f8e4m3_src, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_f8e5m2_group, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_f8e5m2_src, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_f32_group, + builtin_types[get_function_type_index (type_idx)].vector) +DEF_RVV_BASE_TYPE (zvbdota_f32_src, + builtin_types[get_function_type_index (type_idx)].vector) DEF_RVV_BASE_TYPE (fp8e4m3_vector, get_vector_type (type_idx)) DEF_RVV_BASE_TYPE (fp8e5m2_vector, get_vector_type (type_idx)) DEF_RVV_BASE_TYPE (size_ptr, build_pointer_type (size_type_node)) diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h index 10af348c1e6..b8c8eed5a1d 100644 --- a/gcc/config/riscv/riscv-vector-builtins.h +++ b/gcc/config/riscv/riscv-vector-builtins.h @@ -111,6 +111,9 @@ static const unsigned int CP_WRITE_CSR = 1U << 5; #define RVV_REQUIRE_ELEN_FP_16 (1 << 6) /* Require FP ELEN >= 32. */ #define RVV_REQUIRE_ELEN_BF_16 (1 << 7) /* Require BF16. */ #define RVV_REQUIRE_ZVFOFP8MIN (1 << 8) /* Require ZVFOFP8MIN extension. */ +#define RVV_REQUIRE_MIN_VLEN_128 (1 << 9) /* Require TARGET_MIN_VLEN >= 128. */ +#define RVV_REQUIRE_MIN_VLEN_256 (1 << 10) /* Require TARGET_MIN_VLEN >= 256. */ +#define RVV_REQUIRE_MIN_VLEN_512 (1 << 11) /* Require TARGET_MIN_VLEN >= 512. */ /* Sentinel used by builtin expanders for instructions that leave the machine description "altfmt" attribute at its default. */ @@ -139,6 +142,11 @@ enum required_ext ZVQWDOTA16I_EXT, /* Zvqwdota16i extension */ ZVFWDOTA16BF_EXT, /* Zvfwdota16bf extension */ ZVFQWDOTA8F_EXT, /* Zvfqwdota8f extension */ + ZVQWBDOTA8I_EXT, /* Zvqwbdota8i extension */ + ZVQWBDOTA16I_EXT, /* Zvqwbdota16i extension */ + ZVFWBDOTA16BF_EXT, /* Zvfwbdota16bf extension */ + ZVFQWBDOTA8F_EXT, /* Zvfqwbdota8f extension */ + ZVFBDOTA32F_EXT, /* Zvfbdota32f extension */ XSFVQMACCQOQ_EXT, /* XSFVQMACCQOQ extension */ XSFVQMACCDOD_EXT, /* XSFVQMACCDOD extension */ XSFVFNRCLIPXFQF_EXT, /* XSFVFNRCLIPXFQF extension */ @@ -174,6 +182,11 @@ enum rvv_builtin_partition RVV_PARTITION_ZVQWDOTA16I, RVV_PARTITION_ZVFWDOTA16BF, RVV_PARTITION_ZVFQWDOTA8F, + RVV_PARTITION_ZVQWBDOTA8I, + RVV_PARTITION_ZVQWBDOTA16I, + RVV_PARTITION_ZVFWBDOTA16BF, + RVV_PARTITION_ZVFQWBDOTA8F, + RVV_PARTITION_ZVFBDOTA32F, RVV_PARTITION_XSFVQMACCQOQ, RVV_PARTITION_XSFVQMACCDOD, RVV_PARTITION_XSFVFNRCLIPXFQF, @@ -236,6 +249,16 @@ static inline const char * required_ext_to_isa_name (enum required_ext required) return "zvfwdota16bf"; case ZVFQWDOTA8F_EXT: return "zvfqwdota8f"; + case ZVQWBDOTA8I_EXT: + return "zvqwbdota8i"; + case ZVQWBDOTA16I_EXT: + return "zvqwbdota16i"; + case ZVFWBDOTA16BF_EXT: + return "zvfwbdota16bf"; + case ZVFQWBDOTA8F_EXT: + return "zvfqwbdota8f"; + case ZVFBDOTA32F_EXT: + return "zvfbdota32f"; case XSFVQMACCQOQ_EXT: return "xsfvqmaccqoq"; case XSFVQMACCDOD_EXT: @@ -301,6 +324,16 @@ static inline bool required_extensions_specified (enum required_ext required) return TARGET_ZVFWDOTA16BF; case ZVFQWDOTA8F_EXT: return TARGET_ZVFQWDOTA8F; + case ZVQWBDOTA8I_EXT: + return TARGET_ZVQWBDOTA8I; + case ZVQWBDOTA16I_EXT: + return TARGET_ZVQWBDOTA16I; + case ZVFWBDOTA16BF_EXT: + return TARGET_ZVFWBDOTA16BF; + case ZVFQWBDOTA8F_EXT: + return TARGET_ZVFQWBDOTA8F; + case ZVFBDOTA32F_EXT: + return TARGET_ZVFBDOTA32F; case XSFVQMACCQOQ_EXT: return TARGET_XSFVQMACCQOQ; case XSFVQMACCDOD_EXT: @@ -590,6 +623,7 @@ public: rtx use_compare_insn (rtx_code, insn_code); rtx use_ternop_insn (bool, insn_code); rtx use_zvdota_insn (insn_code, unsigned = RVV_NO_ALTFMT); + rtx use_zvbdota_insn (insn_code, unsigned = RVV_NO_ALTFMT); rtx use_widen_ternop_insn (insn_code); rtx use_scalar_move_insn (insn_code); rtx use_scalar_broadcast_insn (insn_code); @@ -674,6 +708,7 @@ public: bool require_immediate (unsigned int, HOST_WIDE_INT, HOST_WIDE_INT) const; bool require_immediate_range_or (unsigned int, HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT) const; + bool require_zvbdota_ci (unsigned int) const; private: bool require_immediate_range (unsigned int, HOST_WIDE_INT, diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-acc-lmul-vlen32-fail.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-acc-lmul-vlen32-fail.c new file mode 100644 index 00000000000..db72ec4ba18 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-acc-lmul-vlen32-fail.c @@ -0,0 +1,59 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zvqwbdota8i_zvfwbdota16bf_zvfbfmin_zvfqwbdota8f_zvfbdota32f -mabi=lp64d -O2" } */ + +#include "riscv_vector.h" + +vuint32m1_t +test_vqwbdota_u32m1 (vuint32m1_t vd, vuint8m8_t vs2, vuint8m1_t vs1, + size_t vl) +{ + return __riscv_vqwbdota_vv_u8m8_u8m1_u32m1 (vd, vs2, vs1, 0, vl); + /* { dg-error "requires the zvl256b ISA extension" "" { target *-*-* } .-1 } */ +} + +vuint32m2_t +test_vqwbdota_u32m2 (vuint32m2_t vd, vuint8m8_t vs2, vuint8m1_t vs1, + size_t vl) +{ + return __riscv_vqwbdota_vv_u8m8_u8m1_u32m2 (vd, vs2, vs1, 0, vl); + /* { dg-error "requires the zvl128b ISA extension" "" { target *-*-* } .-1 } */ +} + +vuint32m4_t +test_vqwbdota_u32m4 (vuint32m4_t vd, vuint8m8_t vs2, vuint8m1_t vs1, + size_t vl) +{ + return __riscv_vqwbdota_vv_u8m8_u8m1_u32m4 (vd, vs2, vs1, 0, vl); + /* { dg-error "requires the zvl64b ISA extension" "" { target *-*-* } .-1 } */ +} + +vuint32m8_t +test_vqwbdota_u32m8 (vuint32m8_t vd, vuint8m8_t vs2, vuint8m1_t vs1, + size_t vl) +{ + return __riscv_vqwbdota_vv_u8m8_u8m1_u32m8 (vd, vs2, vs1, 0, vl); +} + +vfloat32m4_t +test_vfwbdota_f32m4 (vfloat32m4_t vd, vbfloat16m8_t vs2, + vbfloat16m1_t vs1, size_t vl) +{ + return __riscv_vfwbdota_vv_bf16m8_bf16m1_f32m4 (vd, vs2, vs1, 0, vl); + /* { dg-error "requires the zvl64b ISA extension" "" { target *-*-* } .-1 } */ +} + +vfloat32m4_t +test_vfqwbdota_f32m4 (vfloat32m4_t vd, vfloat8e4m3m8_t vs2, + vfloat8e4m3m1_t vs1, size_t vl) +{ + return __riscv_vfqwbdota_vv_f8e4m3m8_f8e4m3m1_f32m4 (vd, vs2, vs1, 0, vl); + /* { dg-error "requires the zvl64b ISA extension" "" { target *-*-* } .-1 } */ +} + +vfloat32m4_t +test_vfbdota_f32m4 (vfloat32m4_t vd, vfloat32m8_t vs2, + vfloat32m1_t vs1, size_t vl) +{ + return __riscv_vfbdota_vv_f32m4 (vd, vs2, vs1, 0, vl); + /* { dg-error "requires the zvl64b ISA extension" "" { target *-*-* } .-1 } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-acc-lmul-vlen64-fail.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-acc-lmul-vlen64-fail.c new file mode 100644 index 00000000000..ae76d599a78 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-acc-lmul-vlen64-fail.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_zvqwbdota16i_zvl64b -mabi=lp64d -O2" } */ + +#include "riscv_vector.h" + +vuint64m1_t +test_vqwbdota_u64m1 (vuint64m1_t vd, vuint16m8_t vs2, vuint16m1_t vs1, + size_t vl) +{ + return __riscv_vqwbdota_vv_u16m8_u16m1_u64m1 (vd, vs2, vs1, 0, vl); + /* { dg-error "requires the zvl512b ISA extension" "" { target *-*-* } .-1 } */ +} + +vuint64m2_t +test_vqwbdota_u64m2 (vuint64m2_t vd, vuint16m8_t vs2, vuint16m1_t vs1, + size_t vl) +{ + return __riscv_vqwbdota_vv_u16m8_u16m1_u64m2 (vd, vs2, vs1, 0, vl); + /* { dg-error "requires the zvl256b ISA extension" "" { target *-*-* } .-1 } */ +} + +vuint64m4_t +test_vqwbdota_u64m4 (vuint64m4_t vd, vuint16m8_t vs2, vuint16m1_t vs1, + size_t vl) +{ + return __riscv_vqwbdota_vv_u16m8_u16m1_u64m4 (vd, vs2, vs1, 0, vl); + /* { dg-error "requires the zvl128b ISA extension" "" { target *-*-* } .-1 } */ +} + +vuint64m8_t +test_vqwbdota_u64m8 (vuint64m8_t vd, vuint16m8_t vs2, vuint16m1_t vs1, + size_t vl) +{ + return __riscv_vqwbdota_vv_u16m8_u16m1_u64m8 (vd, vs2, vs1, 0, vl); +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-ci-invalid.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-ci-invalid.c new file mode 100644 index 00000000000..7e4fb14772b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-ci-invalid.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvqwbdota8i -mabi=lp64d -O2" } */ + +#include "riscv_vector.h" + +vuint32m8_t +test_ci_4 (vuint32m8_t vd, vuint8m8_t vs2, vuint8m1_t vs1, size_t vl) +{ + return __riscv_vqwbdota_vv_u8m8_u8m1_u32m8 (vd, vs2, vs1, 4, vl); + /* { dg-error "argument 4 of '__riscv_vqwbdota_vv_u8m8_u8m1_u32m8' must be a constant multiple of 8 in the range .0, 56." "" { target *-*-* } .-1 } */ +} + +vint32m8_t +test_ci_64 (vint32m8_t vd, vuint8m8_t vs2, vint8m1_t vs1, size_t vl) +{ + return __riscv_vqwbdota_vv_u8m8_i8m1_i32m8 (vd, vs2, vs1, 64, vl); + /* { dg-error "argument 4 of '__riscv_vqwbdota_vv_u8m8_i8m1_i32m8' must be a constant multiple of 8 in the range .0, 56." "" { target *-*-* } .-1 } */ +} + +vint32m8_t +test_ci_minus_8 (vint32m8_t vd, vint8m8_t vs2, vuint8m1_t vs1, size_t vl) +{ + return __riscv_vqwbdota_vv_i8m8_u8m1_i32m8 (vd, vs2, vs1, -8, vl); + /* { dg-error "argument 4 of '__riscv_vqwbdota_vv_i8m8_u8m1_i32m8' must be a constant multiple of 8 in the range .0, 56." "" { target *-*-* } .-1 } */ +} + +vuint32m8_t +test_ci_variable (vuint32m8_t vd, vuint8m8_t vs2, vuint8m1_t vs1, + size_t ci, size_t vl) +{ + return __riscv_vqwbdota_vv_u8m8_u8m1_u32m8 (vd, vs2, vs1, ci, vl); + /* { dg-error "argument 4 of .* must be an integer constant expression" "" { target *-*-* } .-1 } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-intrinsic.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-intrinsic.c new file mode 100644 index 00000000000..7456d0173d7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-intrinsic.c @@ -0,0 +1,135 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvqwbdota8i_zvqwbdota16i_zvfwbdota16bf_zvfqwbdota8f_zvfbdota32f_zvfbfmin_zvl512b -mabi=lp64d -O2" } */ + +#include "riscv_vector.h" + +vuint32m8_t +test_vqwbdota_uu_8 (vuint32m8_t vd, vuint8m8_t vs2, + vuint8m1_t vs1, size_t vl) +{ + return __riscv_vqwbdota_vv_u8m8_u8m1_u32m8 (vd, vs2, vs1, 8, vl); +} + +vint32m8_t +test_vqwbdota_us_8 (vint32m8_t vd, vuint8m8_t vs2, + vint8m1_t vs1, size_t vl) +{ + return __riscv_vqwbdota_vv_u8m8_i8m1_i32m8 (vd, vs2, vs1, 8, vl); +} + +vint32m8_t +test_vqwbdota_su_8 (vint32m8_t vd, vint8m8_t vs2, + vuint8m1_t vs1, size_t vl) +{ + return __riscv_vqwbdota_vv_i8m8_u8m1_i32m8 (vd, vs2, vs1, 8, vl); +} + +vint32m8_t +test_vqwbdota_ss_8 (vint32m8_t vd, vint8m8_t vs2, + vint8m1_t vs1, size_t vl) +{ + return __riscv_vqwbdota_vv_i8m8_i8m1_i32m8 (vd, vs2, vs1, 8, vl); +} + +vuint64m8_t +test_vqwbdota_uu_16 (vuint64m8_t vd, vuint16m8_t vs2, + vuint16m1_t vs1, size_t vl) +{ + return __riscv_vqwbdota_vv_u16m8_u16m1_u64m8 (vd, vs2, vs1, 16, vl); +} + +vint64m8_t +test_vqwbdota_us_16 (vint64m8_t vd, vuint16m8_t vs2, + vint16m1_t vs1, size_t vl) +{ + return __riscv_vqwbdota_vv_u16m8_i16m1_i64m8 (vd, vs2, vs1, 16, vl); +} + +vint64m8_t +test_vqwbdota_su_16 (vint64m8_t vd, vint16m8_t vs2, + vuint16m1_t vs1, size_t vl) +{ + return __riscv_vqwbdota_vv_i16m8_u16m1_i64m8 (vd, vs2, vs1, 16, vl); +} + +vint64m8_t +test_vqwbdota_ss_16 (vint64m8_t vd, vint16m8_t vs2, + vint16m1_t vs1, size_t vl) +{ + return __riscv_vqwbdota_vv_i16m8_i16m1_i64m8 (vd, vs2, vs1, 16, vl); +} + +vfloat32m8_t +test_vfqwbdota_e4m3_e4m3 (vfloat32m8_t vd, vfloat8e4m3m8_t vs2, + vfloat8e4m3m1_t vs1, size_t vl) +{ + return __riscv_vfqwbdota_vv_f8e4m3m8_f8e4m3m1_f32m8 (vd, vs2, vs1, 24, vl); +} + +vfloat32m8_t +test_vfqwbdota_e4m3_e5m2 (vfloat32m8_t vd, vfloat8e4m3m8_t vs2, + vfloat8e5m2m1_t vs1, size_t vl) +{ + return __riscv_vfqwbdota_vv_f8e4m3m8_f8e5m2m1_f32m8 (vd, vs2, vs1, 24, vl); +} + +vfloat32m8_t +test_vfqwbdota_e5m2_e4m3 (vfloat32m8_t vd, vfloat8e5m2m8_t vs2, + vfloat8e4m3m1_t vs1, size_t vl) +{ + return __riscv_vfqwbdota_vv_f8e5m2m8_f8e4m3m1_f32m8 (vd, vs2, vs1, 32, vl); +} + +vfloat32m8_t +test_vfqwbdota_e5m2_e5m2 (vfloat32m8_t vd, vfloat8e5m2m8_t vs2, + vfloat8e5m2m1_t vs1, size_t vl) +{ + return __riscv_vfqwbdota_vv_f8e5m2m8_f8e5m2m1_f32m8 (vd, vs2, vs1, 32, vl); +} + +vfloat32m8_t +test_vfwbdota_bf16 (vfloat32m8_t vd, vbfloat16m8_t vs2, + vbfloat16m1_t vs1, size_t vl) +{ + return __riscv_vfwbdota_vv_bf16m8_bf16m1_f32m8 (vd, vs2, vs1, 40, vl); +} + +vfloat32m8_t +test_vfbdota (vfloat32m8_t vd, vfloat32m8_t vs2, + vfloat32m1_t vs1, size_t vl) +{ + return __riscv_vfbdota_vv_f32m8 (vd, vs2, vs1, 48, vl); +} + +vfloat32m8_t +test_vfbdota_rm (vfloat32m8_t vd, vfloat32m8_t vs2, + vfloat32m1_t vs1, size_t vl) +{ + return __riscv_vfbdota_vv_f32m8_rm (vd, vs2, vs1, 56, + __RISCV_FRM_RDN, vl); +} + +/* { dg-final { scan-assembler-times {vqwbdotau\.vv} 4 } } */ +/* { dg-final { scan-assembler-times {vqwbdotas\.vv} 4 } } */ +/* { dg-final { scan-assembler-times {vfqwbdota\.vv} 2 } } */ +/* { dg-final { scan-assembler-times {vfqwbdota\.alt\.vv} 2 } } */ +/* { dg-final { scan-assembler-times {vfwbdota\.vv} 1 } } */ +/* { dg-final { scan-assembler-times {vfbdota\.vv} 2 } } */ + +/* { dg-final { scan-assembler-times {vqwbdotau\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*8} 2 } } */ +/* { dg-final { scan-assembler-times {vqwbdotas\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*8} 2 } } */ +/* { dg-final { scan-assembler-times {vqwbdotau\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*16} 2 } } */ +/* { dg-final { scan-assembler-times {vqwbdotas\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*16} 2 } } */ +/* { dg-final { scan-assembler-times {vfqwbdota\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*24} 2 } } */ +/* { dg-final { scan-assembler-times {vfqwbdota\.alt\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*32} 2 } } */ +/* { dg-final { scan-assembler-times {vfwbdota\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*40} 1 } } */ +/* { dg-final { scan-assembler-times {vfbdota\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*48} 1 } } */ +/* { dg-final { scan-assembler-times {vfbdota\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*56} 1 } } */ + +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-z0-9]+,\s*e8,\s*m1,\s*ta,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-z0-9]+,\s*e8alt,\s*m1,\s*ta,\s*ma} 4 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-z0-9]+,\s*e16,\s*m1,\s*ta,\s*ma} 2 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-z0-9]+,\s*e16alt,\s*m1,\s*ta,\s*ma} 3 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-z0-9]+,\s*e32,\s*m1,\s*ta,\s*ma} 2 } } */ +/* { dg-final { scan-assembler-times {fsrmi\s+[0-4]} 1 } } */ +/* { dg-final { scan-assembler-times {fsrm\s+[a-z0-9]+} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-no-rm-fail.c b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-no-rm-fail.c new file mode 100644 index 00000000000..03b1f5fc05e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvbdota-no-rm-fail.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvfwbdota16bf_zvfqwbdota8f_zvfbfmin_zvl512b -mabi=lp64d -O2 -Werror=implicit-function-declaration" } */ + +#include "riscv_vector.h" + +void +test_vfwbdota_rm (vfloat32m8_t vd, vbfloat16m8_t vs2, + vbfloat16m1_t vs1, size_t vl) +{ + (void) __riscv_vfwbdota_vv_bf16m8_bf16m1_f32m8_rm (vd, vs2, vs1, 0, __RISCV_FRM_RNE, vl); /* { dg-error "implicit declaration of function" } */ +} + +void +test_vfqwbdota_rm (vfloat32m8_t vd, vfloat8e4m3m8_t vs2, + vfloat8e4m3m1_t vs1, size_t vl) +{ + (void) __riscv_vfqwbdota_vv_f8e4m3m8_f8e4m3m1_f32m8_rm (vd, vs2, vs1, 8, __RISCV_FRM_RNE, vl); /* { dg-error "implicit declaration of function" } */ +} + +void +test_vfqwbdota_e5m2_rm (vfloat32m8_t vd, vfloat8e5m2m8_t vs2, + vfloat8e4m3m1_t vs1, size_t vl) +{ + (void) __riscv_vfqwbdota_vv_f8e5m2m8_f8e4m3m1_f32m8_rm (vd, vs2, vs1, 16, __RISCV_FRM_RNE, vl); /* { dg-error "implicit declaration of function" } */ +} -- 2.43.0
