Message ID | 20240408080957.647668-1-pan2.li@intel.com |
---|---|
State | New |
Headers | show |
Series | [v1] RISC-V: Refine the error msg for RVV intrinisc required ext | expand |
LGTM. Thanks. juzhe.zhong@rivai.ai From: pan2.li Date: 2024-04-08 16:09 To: gcc-patches CC: juzhe.zhong; kito.cheng; Pan Li Subject: [PATCH v1] RISC-V: Refine the error msg for RVV intrinisc required ext From: Pan Li <pan2.li@intel.com> The RVV intrinisc API has sorts of required extension from both the march or target attribute. It will have error message similar to below: built-in function '__riscv_vsetvl_e8m4\(vl\)' requires the V ISA extension However, it is not accurate as we have many additional sub extenstion besides v extension. For example, zvbb, zvbk, zvbc ... etc. This patch would like to refine the error message with a friendly hint for the required extension. For example as below: vuint64m1_t __attribute__((target("arch=+v"))) test_1 (vuint64m1_t op_1, vuint64m1_t op_2, size_t vl) { return __riscv_vclmul_vv_u64m1 (op_1, op_2, vl); } When compile with march=rv64gc and target arch=+v, we will have error message as below: error: built-in function '__riscv_vclmul_vv_u64m1(op_1, op_2, vl)' requires the 'zvbc' ISA extension Then the end-user will get the point that the *zvbc* extension is missing for the intrinisc API easily. gcc/ChangeLog: * config/riscv/riscv-vector-builtins-shapes.cc (build_one): Pass required_ext arg when invoke add function. (build_th_loadstore): Ditto. (struct vcreate_def): Ditto. (struct read_vl_def): Ditto. (struct vlenb_def): Ditto. * config/riscv/riscv-vector-builtins.cc (function_builder::add_function): Introduce new arg required_ext to fill in the register func. (function_builder::add_unique_function): Ditto. (function_builder::add_overloaded_function): Ditto. (expand_builtin): Leverage required_extensions_specified to check if the required extension is provided. * config/riscv/riscv-vector-builtins.h (reqired_ext_to_isa_name): New func impl to convert the required_ext enum to the extension name. (required_extensions_specified): New func impl to predicate if the required extension is well feeded. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-7.c: Adjust the error message for v extension. * gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-8.c: Ditto. * gcc.target/riscv/rvv/base/intrinsic_required_ext-1.c: New test. * gcc.target/riscv/rvv/base/intrinsic_required_ext-10.c: New test. * gcc.target/riscv/rvv/base/intrinsic_required_ext-2.c: New test. * gcc.target/riscv/rvv/base/intrinsic_required_ext-3.c: New test. * gcc.target/riscv/rvv/base/intrinsic_required_ext-4.c: New test. * gcc.target/riscv/rvv/base/intrinsic_required_ext-5.c: New test. * gcc.target/riscv/rvv/base/intrinsic_required_ext-6.c: New test. * gcc.target/riscv/rvv/base/intrinsic_required_ext-7.c: New test. * gcc.target/riscv/rvv/base/intrinsic_required_ext-8.c: New test. * gcc.target/riscv/rvv/base/intrinsic_required_ext-9.c: New test. Signed-off-by: Pan Li <pan2.li@intel.com> --- .../riscv/riscv-vector-builtins-shapes.cc | 18 +++-- gcc/config/riscv/riscv-vector-builtins.cc | 23 ++++-- gcc/config/riscv/riscv-vector-builtins.h | 75 ++++++++++++++++++- .../riscv/rvv/base/intrinsic_required_ext-1.c | 10 +++ .../rvv/base/intrinsic_required_ext-10.c | 11 +++ .../riscv/rvv/base/intrinsic_required_ext-2.c | 11 +++ .../riscv/rvv/base/intrinsic_required_ext-3.c | 11 +++ .../riscv/rvv/base/intrinsic_required_ext-4.c | 11 +++ .../riscv/rvv/base/intrinsic_required_ext-5.c | 11 +++ .../riscv/rvv/base/intrinsic_required_ext-6.c | 11 +++ .../riscv/rvv/base/intrinsic_required_ext-7.c | 11 +++ .../riscv/rvv/base/intrinsic_required_ext-8.c | 11 +++ .../riscv/rvv/base/intrinsic_required_ext-9.c | 11 +++ .../target_attribute_v_with_intrinsic-7.c | 2 +- .../target_attribute_v_with_intrinsic-8.c | 2 +- 15 files changed, 210 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-9.c diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc index c5ffcc1f2c4..7f983e82370 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc @@ -72,9 +72,10 @@ build_one (function_builder &b, const function_group_info &group, if (TARGET_XTHEADVECTOR && !check_type (return_type, argument_types)) return; - b.add_overloaded_function (function_instance, *group.shape); + b.add_overloaded_function (function_instance, *group.shape, + group.required_extensions); b.add_unique_function (function_instance, (*group.shape), return_type, - argument_types); + argument_types, group.required_extensions); } /* Add a function instance for every operand && predicate && args @@ -249,9 +250,10 @@ build_th_loadstore (function_builder &b, const function_group_info &group, if (strstr (group.base_name, "w") && (sew == 8 || sew ==16)) return; - b.add_overloaded_function (function_instance, *group.shape); + b.add_overloaded_function (function_instance, *group.shape, + group.required_extensions); b.add_unique_function (function_instance, (*group.shape), return_type, - argument_types); + argument_types, group.required_extensions); } /* th_loadstore_width_def class. */ @@ -931,7 +933,7 @@ struct vcreate_def : public build_base argument_types.quick_push (arg_type); b.add_unique_function (function_instance, (*group.shape), return_type, - argument_types); + argument_types, group.required_extensions); } } @@ -966,7 +968,8 @@ struct read_vl_def : public function_shape { auto_vec<tree> argument_types; b.add_unique_function (get_read_vl_instance (), (*group.shape), - size_type_node, argument_types); + size_type_node, argument_types, + group.required_extensions); } char *get_name (function_builder &b, const function_instance &instance, @@ -1024,7 +1027,8 @@ struct vlenb_def : public function_shape *group.shape, group.ops_infos.types[0], group.preds[0], &group.ops_infos); b.add_unique_function (function_instance, (*group.shape), - long_unsigned_type_node, argument_types); + long_unsigned_type_node, argument_types, + group.required_extensions); } char *get_name (function_builder &b, const function_instance &instance, diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 53ccea7889e..192a6c230d1 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -106,6 +106,9 @@ public: /* Generate hash value based on the overload_name and the argument list passed by the user when calling. */ hashval_t overloaded_hash (const vec<tree, va_gc> &); + + /* The reqired extension for the register function. */ + enum required_ext required; }; /* Hash traits for registered_function. */ @@ -3701,6 +3704,7 @@ function_builder::add_function (const function_instance &instance, const char *name, tree fntype, tree attrs, bool placeholder_p, const char *overload_name, const vec<tree> &argument_types, + enum required_ext required, bool overloaded_p = false) { unsigned int code = vec_safe_length (registered_functions); @@ -3730,6 +3734,7 @@ function_builder::add_function (const function_instance &instance, rfn.overload_name = overload_name ? xstrdup (overload_name) : NULL; rfn.argument_types = argument_types; rfn.overloaded_p = overloaded_p; + rfn.required = required; vec_safe_push (registered_functions, &rfn); return rfn; @@ -3744,7 +3749,8 @@ void function_builder::add_unique_function (const function_instance &instance, const function_shape *shape, tree return_type, - vec<tree> &argument_types) + vec<tree> &argument_types, + enum required_ext required) { /* Do not add this function if it is invalid. */ if (!check_required_extensions (instance)) @@ -3762,7 +3768,7 @@ function_builder::add_unique_function (const function_instance &instance, tree attrs = get_attributes (instance); registered_function &rfn = add_function (instance, name, fntype, attrs, false, overload_name, - argument_types.copy ()); + argument_types.copy (), required); /* Enter the function into the hash table. */ hashval_t hash = instance.hash (); @@ -3777,7 +3783,7 @@ function_builder::add_unique_function (const function_instance &instance, tree attrs = get_attributes (instance); bool placeholder_p = !m_direct_overloads; add_function (instance, overload_name, fntype, attrs, placeholder_p, NULL, - vNULL); + vNULL, required); /* Enter the function into the non-overloaded hash table. */ hash = rfn.overloaded_hash (); @@ -3792,7 +3798,8 @@ function_builder::add_unique_function (const function_instance &instance, /* Add overloaded function for gcc. */ void function_builder::add_overloaded_function (const function_instance &instance, - const function_shape *shape) + const function_shape *shape, + enum required_ext required) { if (!check_required_extensions (instance)) return; @@ -3805,7 +3812,7 @@ function_builder::add_overloaded_function (const function_instance &instance, for the overloaded function. */ tree fntype = build_function_type (void_type_node, void_list_node); add_function (instance, name, fntype, NULL_TREE, m_direct_overloads, name, - vNULL, true); + vNULL, required, true); obstack_free (&m_string_obstack, name); } } @@ -4633,10 +4640,12 @@ expand_builtin (unsigned int code, tree exp, rtx target) { registered_function &rfn = *(*registered_functions)[code]; - if (!TARGET_VECTOR) + if (!required_extensions_specified (rfn.required)) { error_at (EXPR_LOCATION (exp), - "built-in function %qE requires the V ISA extension", exp); + "built-in function %qE requires the %qs ISA extension", + exp, + reqired_ext_to_isa_name (rfn.required)); return target; } diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h index 22fed60b4c3..05d18ae1322 100644 --- a/gcc/config/riscv/riscv-vector-builtins.h +++ b/gcc/config/riscv/riscv-vector-builtins.h @@ -124,8 +124,75 @@ enum required_ext ZVKSED_EXT, /* Crypto vector Zvksed sub-ext */ ZVKSH_EXT, /* Crypto vector Zvksh sub-ext */ XTHEADVECTOR_EXT, /* XTheadVector extension */ + /* Please update below to isa_name func when add or remove enum type(s). */ }; +static inline const char * reqired_ext_to_isa_name (enum required_ext required) +{ + switch (required) + { + case VECTOR_EXT: + return "v"; + case ZVBB_EXT: + return "zvbb"; + case ZVBB_OR_ZVKB_EXT: + return "zvbb or zvkb"; + case ZVBC_EXT: + return "zvbc"; + case ZVKG_EXT: + return "zvkg"; + case ZVKNED_EXT: + return "zvkned"; + case ZVKNHA_OR_ZVKNHB_EXT: + return "zvknha or zvknhb"; + case ZVKNHB_EXT: + return "zvknhb"; + case ZVKSED_EXT: + return "zvksed"; + case ZVKSH_EXT: + return "zvksh"; + case XTHEADVECTOR_EXT: + return "xthreadvector"; + default: + gcc_unreachable (); + } + + gcc_unreachable (); +} + +static inline bool required_extensions_specified (enum required_ext required) +{ + switch (required) + { + case VECTOR_EXT: + return TARGET_VECTOR;; + case ZVBB_EXT: + return TARGET_ZVBB; + case ZVBB_OR_ZVKB_EXT: + return TARGET_ZVBB || TARGET_ZVKB; + case ZVBC_EXT: + return TARGET_ZVBC; + case ZVKG_EXT: + return TARGET_ZVKG; + case ZVKNED_EXT: + return TARGET_ZVKNED; + case ZVKNHA_OR_ZVKNHB_EXT: + return TARGET_ZVKNHA || TARGET_ZVKNHB; + case ZVKNHB_EXT: + return TARGET_ZVKNHB; + case ZVKSED_EXT: + return TARGET_ZVKSED; + case ZVKSH_EXT: + return TARGET_ZVKSH; + case XTHEADVECTOR_EXT: + return TARGET_XTHEADVECTOR; + default: + gcc_unreachable (); + } + + gcc_unreachable (); +} + /* Enumerates the RVV operand types. */ enum operand_type_index { @@ -325,9 +392,10 @@ public: void allocate_argument_types (const function_instance &, vec<tree> &) const; void apply_predication (const function_instance &, tree, vec<tree> &) const; void add_unique_function (const function_instance &, const function_shape *, - tree, vec<tree> &); + tree, vec<tree> &, enum required_ext); void add_overloaded_function (const function_instance &, - const function_shape *); + const function_shape *, + enum required_ext); void register_function_group (const function_group_info &); void append_name (const char *); void append_base_name (const char *); @@ -340,7 +408,8 @@ private: registered_function &add_function (const function_instance &, const char *, tree, tree, bool, const char *, - const vec<tree> &, bool); + const vec<tree> &, enum required_ext, + bool); /* True if we should create a separate decl for each instance of an overloaded function, instead of using function_builder. */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-1.c new file mode 100644 index 00000000000..143a3d66016 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +size_t +test_3 (size_t vl) +{ + return __riscv_vsetvl_e8m4 (vl); /* { dg-error {built-in function '__riscv_vsetvl_e8m4\(vl\)' requires the 'v' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-10.c new file mode 100644 index 00000000000..b0a9851d4c7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-10.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint32m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint32m1_t op_1, vuint32m1_t op_2, size_t vl) +{ + return __riscv_vsm3me_vv_u32m1 (op_1, op_2, vl); /* { dg-error {built-in function '__riscv_vsm3me_vv_u32m1\(op_1, op_2, vl\)' requires the 'zvksh' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-2.c new file mode 100644 index 00000000000..20ab9775a1e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint32m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint32m1_t op_1, vuint32m1_t op_2, size_t vl) +{ + return __riscv_vandn_vv_u32m1 (op_1, op_2, vl); /* { dg-error {built-in function '__riscv_vandn_vv_u32m1\(op_1, op_2, vl\)' requires the 'zvbb or zvkb' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-3.c new file mode 100644 index 00000000000..9b7d37f5b33 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint32m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint32m1_t op_1, size_t vl) +{ + return __riscv_vclz_v_u32m1 (op_1, vl); /* { dg-error {built-in function '__riscv_vclz_v_u32m1\(op_1, vl\)' requires the 'zvbb' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-4.c new file mode 100644 index 00000000000..fdaab62b17d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-4.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint64m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint64m1_t op_1, vuint64m1_t op_2, size_t vl) +{ + return __riscv_vclmul_vv_u64m1 (op_1, op_2, vl); /* { dg-error {built-in function '__riscv_vclmul_vv_u64m1\(op_1, op_2, vl\)' requires the 'zvbc' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-5.c new file mode 100644 index 00000000000..6a4bb431f4a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-5.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint32m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint32m1_t dest, vuint32m1_t op_1, vuint32m1_t op_2, size_t vl) +{ + return __riscv_vghsh_vv_u32m1 (dest, op_1, op_2, vl); /* { dg-error {built-in function '__riscv_vghsh_vv_u32m1\(dest, op_1, op_2, vl\)' requires the 'zvkg' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-6.c new file mode 100644 index 00000000000..943a2cf653b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-6.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint32m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint32m1_t dest, vuint32mf2_t op_1, size_t vl) +{ + return __riscv_vaesef_vs_u32mf2_u32m1 (dest, op_1, vl); /* { dg-error {built-in function '__riscv_vaesef_vs_u32mf2_u32m1\(dest, op_1, vl\)' requires the 'zvkned' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-7.c new file mode 100644 index 00000000000..c2ccb739f6e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-7.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint32m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint32m1_t dest, vuint32m1_t op_1, vuint32m1_t op_2, size_t vl) +{ + return __riscv_vsha2ms_vv_u32m1 (dest, op_1, op_2, vl); /* { dg-error {built-in function '__riscv_vsha2ms_vv_u32m1\(dest, op_1, op_2, vl\)' requires the 'zvknha or zvknhb' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-8.c new file mode 100644 index 00000000000..e4312cc0530 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-8.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint64m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint64m1_t dest, vuint64m1_t op_1, vuint64m1_t op_2, size_t vl) +{ + return __riscv_vsha2ms_vv_u64m1 (dest, op_1, op_2, vl); /* { dg-error {built-in function '__riscv_vsha2ms_vv_u64m1\(dest, op_1, op_2, vl\)' requires the 'zvknhb' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-9.c new file mode 100644 index 00000000000..442d4917053 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-9.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint32m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint32m1_t op_1, size_t vl) +{ + return __riscv_vsm4k_vi_u32m1 (op_1, 0, vl); /* { dg-error {built-in function '__riscv_vsm4k_vi_u32m1\(op_1, 0, vl\)' requires the 'zvksed' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-7.c index a4cd67f4f95..d1dd811d14b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-7.c @@ -5,5 +5,5 @@ size_t test_1 (size_t vl) { - return __riscv_vsetvl_e8m4 (vl); /* { dg-error {built-in function '__riscv_vsetvl_e8m4\(vl\)' requires the V ISA extension} } */ + return __riscv_vsetvl_e8m4 (vl); /* { dg-error {built-in function '__riscv_vsetvl_e8m4\(vl\)' requires the 'v' ISA extension} } */ } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-8.c index 06ed9a9eddc..9ff4c238124 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-8.c @@ -19,5 +19,5 @@ test_2 () size_t test_3 (size_t vl) { - return __riscv_vsetvl_e8m4 (vl); /* { dg-error {built-in function '__riscv_vsetvl_e8m4\(vl\)' requires the V ISA extension} } */ + return __riscv_vsetvl_e8m4 (vl); /* { dg-error {built-in function '__riscv_vsetvl_e8m4\(vl\)' requires the 'v' ISA extension} } */ }
Committed, thanks Juzhe.
Pan
From: juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai>
Sent: Monday, April 8, 2024 4:13 PM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: kito.cheng <kito.cheng@gmail.com>; Li, Pan2 <pan2.li@intel.com>
Subject: Re: [PATCH v1] RISC-V: Refine the error msg for RVV intrinisc required ext
LGTM. Thanks.
diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc index c5ffcc1f2c4..7f983e82370 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc @@ -72,9 +72,10 @@ build_one (function_builder &b, const function_group_info &group, if (TARGET_XTHEADVECTOR && !check_type (return_type, argument_types)) return; - b.add_overloaded_function (function_instance, *group.shape); + b.add_overloaded_function (function_instance, *group.shape, + group.required_extensions); b.add_unique_function (function_instance, (*group.shape), return_type, - argument_types); + argument_types, group.required_extensions); } /* Add a function instance for every operand && predicate && args @@ -249,9 +250,10 @@ build_th_loadstore (function_builder &b, const function_group_info &group, if (strstr (group.base_name, "w") && (sew == 8 || sew ==16)) return; - b.add_overloaded_function (function_instance, *group.shape); + b.add_overloaded_function (function_instance, *group.shape, + group.required_extensions); b.add_unique_function (function_instance, (*group.shape), return_type, - argument_types); + argument_types, group.required_extensions); } /* th_loadstore_width_def class. */ @@ -931,7 +933,7 @@ struct vcreate_def : public build_base argument_types.quick_push (arg_type); b.add_unique_function (function_instance, (*group.shape), return_type, - argument_types); + argument_types, group.required_extensions); } } @@ -966,7 +968,8 @@ struct read_vl_def : public function_shape { auto_vec<tree> argument_types; b.add_unique_function (get_read_vl_instance (), (*group.shape), - size_type_node, argument_types); + size_type_node, argument_types, + group.required_extensions); } char *get_name (function_builder &b, const function_instance &instance, @@ -1024,7 +1027,8 @@ struct vlenb_def : public function_shape *group.shape, group.ops_infos.types[0], group.preds[0], &group.ops_infos); b.add_unique_function (function_instance, (*group.shape), - long_unsigned_type_node, argument_types); + long_unsigned_type_node, argument_types, + group.required_extensions); } char *get_name (function_builder &b, const function_instance &instance, diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 53ccea7889e..192a6c230d1 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -106,6 +106,9 @@ public: /* Generate hash value based on the overload_name and the argument list passed by the user when calling. */ hashval_t overloaded_hash (const vec<tree, va_gc> &); + + /* The reqired extension for the register function. */ + enum required_ext required; }; /* Hash traits for registered_function. */ @@ -3701,6 +3704,7 @@ function_builder::add_function (const function_instance &instance, const char *name, tree fntype, tree attrs, bool placeholder_p, const char *overload_name, const vec<tree> &argument_types, + enum required_ext required, bool overloaded_p = false) { unsigned int code = vec_safe_length (registered_functions); @@ -3730,6 +3734,7 @@ function_builder::add_function (const function_instance &instance, rfn.overload_name = overload_name ? xstrdup (overload_name) : NULL; rfn.argument_types = argument_types; rfn.overloaded_p = overloaded_p; + rfn.required = required; vec_safe_push (registered_functions, &rfn); return rfn; @@ -3744,7 +3749,8 @@ void function_builder::add_unique_function (const function_instance &instance, const function_shape *shape, tree return_type, - vec<tree> &argument_types) + vec<tree> &argument_types, + enum required_ext required) { /* Do not add this function if it is invalid. */ if (!check_required_extensions (instance)) @@ -3762,7 +3768,7 @@ function_builder::add_unique_function (const function_instance &instance, tree attrs = get_attributes (instance); registered_function &rfn = add_function (instance, name, fntype, attrs, false, overload_name, - argument_types.copy ()); + argument_types.copy (), required); /* Enter the function into the hash table. */ hashval_t hash = instance.hash (); @@ -3777,7 +3783,7 @@ function_builder::add_unique_function (const function_instance &instance, tree attrs = get_attributes (instance); bool placeholder_p = !m_direct_overloads; add_function (instance, overload_name, fntype, attrs, placeholder_p, NULL, - vNULL); + vNULL, required); /* Enter the function into the non-overloaded hash table. */ hash = rfn.overloaded_hash (); @@ -3792,7 +3798,8 @@ function_builder::add_unique_function (const function_instance &instance, /* Add overloaded function for gcc. */ void function_builder::add_overloaded_function (const function_instance &instance, - const function_shape *shape) + const function_shape *shape, + enum required_ext required) { if (!check_required_extensions (instance)) return; @@ -3805,7 +3812,7 @@ function_builder::add_overloaded_function (const function_instance &instance, for the overloaded function. */ tree fntype = build_function_type (void_type_node, void_list_node); add_function (instance, name, fntype, NULL_TREE, m_direct_overloads, name, - vNULL, true); + vNULL, required, true); obstack_free (&m_string_obstack, name); } } @@ -4633,10 +4640,12 @@ expand_builtin (unsigned int code, tree exp, rtx target) { registered_function &rfn = *(*registered_functions)[code]; - if (!TARGET_VECTOR) + if (!required_extensions_specified (rfn.required)) { error_at (EXPR_LOCATION (exp), - "built-in function %qE requires the V ISA extension", exp); + "built-in function %qE requires the %qs ISA extension", + exp, + reqired_ext_to_isa_name (rfn.required)); return target; } diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h index 22fed60b4c3..05d18ae1322 100644 --- a/gcc/config/riscv/riscv-vector-builtins.h +++ b/gcc/config/riscv/riscv-vector-builtins.h @@ -124,8 +124,75 @@ enum required_ext ZVKSED_EXT, /* Crypto vector Zvksed sub-ext */ ZVKSH_EXT, /* Crypto vector Zvksh sub-ext */ XTHEADVECTOR_EXT, /* XTheadVector extension */ + /* Please update below to isa_name func when add or remove enum type(s). */ }; +static inline const char * reqired_ext_to_isa_name (enum required_ext required) +{ + switch (required) + { + case VECTOR_EXT: + return "v"; + case ZVBB_EXT: + return "zvbb"; + case ZVBB_OR_ZVKB_EXT: + return "zvbb or zvkb"; + case ZVBC_EXT: + return "zvbc"; + case ZVKG_EXT: + return "zvkg"; + case ZVKNED_EXT: + return "zvkned"; + case ZVKNHA_OR_ZVKNHB_EXT: + return "zvknha or zvknhb"; + case ZVKNHB_EXT: + return "zvknhb"; + case ZVKSED_EXT: + return "zvksed"; + case ZVKSH_EXT: + return "zvksh"; + case XTHEADVECTOR_EXT: + return "xthreadvector"; + default: + gcc_unreachable (); + } + + gcc_unreachable (); +} + +static inline bool required_extensions_specified (enum required_ext required) +{ + switch (required) + { + case VECTOR_EXT: + return TARGET_VECTOR;; + case ZVBB_EXT: + return TARGET_ZVBB; + case ZVBB_OR_ZVKB_EXT: + return TARGET_ZVBB || TARGET_ZVKB; + case ZVBC_EXT: + return TARGET_ZVBC; + case ZVKG_EXT: + return TARGET_ZVKG; + case ZVKNED_EXT: + return TARGET_ZVKNED; + case ZVKNHA_OR_ZVKNHB_EXT: + return TARGET_ZVKNHA || TARGET_ZVKNHB; + case ZVKNHB_EXT: + return TARGET_ZVKNHB; + case ZVKSED_EXT: + return TARGET_ZVKSED; + case ZVKSH_EXT: + return TARGET_ZVKSH; + case XTHEADVECTOR_EXT: + return TARGET_XTHEADVECTOR; + default: + gcc_unreachable (); + } + + gcc_unreachable (); +} + /* Enumerates the RVV operand types. */ enum operand_type_index { @@ -325,9 +392,10 @@ public: void allocate_argument_types (const function_instance &, vec<tree> &) const; void apply_predication (const function_instance &, tree, vec<tree> &) const; void add_unique_function (const function_instance &, const function_shape *, - tree, vec<tree> &); + tree, vec<tree> &, enum required_ext); void add_overloaded_function (const function_instance &, - const function_shape *); + const function_shape *, + enum required_ext); void register_function_group (const function_group_info &); void append_name (const char *); void append_base_name (const char *); @@ -340,7 +408,8 @@ private: registered_function &add_function (const function_instance &, const char *, tree, tree, bool, const char *, - const vec<tree> &, bool); + const vec<tree> &, enum required_ext, + bool); /* True if we should create a separate decl for each instance of an overloaded function, instead of using function_builder. */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-1.c new file mode 100644 index 00000000000..143a3d66016 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-1.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +size_t +test_3 (size_t vl) +{ + return __riscv_vsetvl_e8m4 (vl); /* { dg-error {built-in function '__riscv_vsetvl_e8m4\(vl\)' requires the 'v' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-10.c new file mode 100644 index 00000000000..b0a9851d4c7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-10.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint32m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint32m1_t op_1, vuint32m1_t op_2, size_t vl) +{ + return __riscv_vsm3me_vv_u32m1 (op_1, op_2, vl); /* { dg-error {built-in function '__riscv_vsm3me_vv_u32m1\(op_1, op_2, vl\)' requires the 'zvksh' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-2.c new file mode 100644 index 00000000000..20ab9775a1e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint32m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint32m1_t op_1, vuint32m1_t op_2, size_t vl) +{ + return __riscv_vandn_vv_u32m1 (op_1, op_2, vl); /* { dg-error {built-in function '__riscv_vandn_vv_u32m1\(op_1, op_2, vl\)' requires the 'zvbb or zvkb' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-3.c new file mode 100644 index 00000000000..9b7d37f5b33 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint32m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint32m1_t op_1, size_t vl) +{ + return __riscv_vclz_v_u32m1 (op_1, vl); /* { dg-error {built-in function '__riscv_vclz_v_u32m1\(op_1, vl\)' requires the 'zvbb' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-4.c new file mode 100644 index 00000000000..fdaab62b17d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-4.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint64m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint64m1_t op_1, vuint64m1_t op_2, size_t vl) +{ + return __riscv_vclmul_vv_u64m1 (op_1, op_2, vl); /* { dg-error {built-in function '__riscv_vclmul_vv_u64m1\(op_1, op_2, vl\)' requires the 'zvbc' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-5.c new file mode 100644 index 00000000000..6a4bb431f4a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-5.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint32m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint32m1_t dest, vuint32m1_t op_1, vuint32m1_t op_2, size_t vl) +{ + return __riscv_vghsh_vv_u32m1 (dest, op_1, op_2, vl); /* { dg-error {built-in function '__riscv_vghsh_vv_u32m1\(dest, op_1, op_2, vl\)' requires the 'zvkg' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-6.c new file mode 100644 index 00000000000..943a2cf653b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-6.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint32m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint32m1_t dest, vuint32mf2_t op_1, size_t vl) +{ + return __riscv_vaesef_vs_u32mf2_u32m1 (dest, op_1, vl); /* { dg-error {built-in function '__riscv_vaesef_vs_u32mf2_u32m1\(dest, op_1, vl\)' requires the 'zvkned' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-7.c new file mode 100644 index 00000000000..c2ccb739f6e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-7.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint32m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint32m1_t dest, vuint32m1_t op_1, vuint32m1_t op_2, size_t vl) +{ + return __riscv_vsha2ms_vv_u32m1 (dest, op_1, op_2, vl); /* { dg-error {built-in function '__riscv_vsha2ms_vv_u32m1\(dest, op_1, op_2, vl\)' requires the 'zvknha or zvknhb' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-8.c new file mode 100644 index 00000000000..e4312cc0530 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-8.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint64m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint64m1_t dest, vuint64m1_t op_1, vuint64m1_t op_2, size_t vl) +{ + return __riscv_vsha2ms_vv_u64m1 (dest, op_1, op_2, vl); /* { dg-error {built-in function '__riscv_vsha2ms_vv_u64m1\(dest, op_1, op_2, vl\)' requires the 'zvknhb' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-9.c new file mode 100644 index 00000000000..442d4917053 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic_required_ext-9.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc -mabi=lp64d -O3" } */ + +#include "riscv_vector.h" + +vuint32m1_t +__attribute__((target("arch=+v"))) +test_1 (vuint32m1_t op_1, size_t vl) +{ + return __riscv_vsm4k_vi_u32m1 (op_1, 0, vl); /* { dg-error {built-in function '__riscv_vsm4k_vi_u32m1\(op_1, 0, vl\)' requires the 'zvksed' ISA extension} } */ +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-7.c index a4cd67f4f95..d1dd811d14b 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-7.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-7.c @@ -5,5 +5,5 @@ size_t test_1 (size_t vl) { - return __riscv_vsetvl_e8m4 (vl); /* { dg-error {built-in function '__riscv_vsetvl_e8m4\(vl\)' requires the V ISA extension} } */ + return __riscv_vsetvl_e8m4 (vl); /* { dg-error {built-in function '__riscv_vsetvl_e8m4\(vl\)' requires the 'v' ISA extension} } */ } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-8.c index 06ed9a9eddc..9ff4c238124 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-8.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/target_attribute_v_with_intrinsic-8.c @@ -19,5 +19,5 @@ test_2 () size_t test_3 (size_t vl) { - return __riscv_vsetvl_e8m4 (vl); /* { dg-error {built-in function '__riscv_vsetvl_e8m4\(vl\)' requires the V ISA extension} } */ + return __riscv_vsetvl_e8m4 (vl); /* { dg-error {built-in function '__riscv_vsetvl_e8m4\(vl\)' requires the 'v' ISA extension} } */ }