I think you can change binop template. Add bool MAY_REQUIRE_FRM = false. By the way, rename maybe_require_frm_p into may_require_frm_p Thanks. juzhe.zhong@rivai.ai From: Li Xu Date: 2023-10-31 13:14 To: juzhe.zhong; gcc-patches CC: kito.cheng; palmer Subject: Re: Re: [PATCH V5] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic Since the following three instances share the class binop, I cannot distinguish between vadd and vfadd. I think it is difficult to add maybe_require_frm_p and maybe_require_vxrm_p to function_base. static CONSTEXPR const binop vadd_obj; static CONSTEXPR const binop vfadd_obj; static CONSTEXPR const binop vfadd_frm_obj; template class binop : public function_base { public: bool maybe_require_frm_p () const override { return true; }//vadd is true ... } -------------- Li Xu >+static bool >+maybe_require_frm_p (function_instance &instance) >+{ >+ return instance.base == bases::vfwredusum >+ || instance.base == bases::vfwredosum || instance.base == bases::vfadd >+ || instance.base == bases::vfwsub || instance.base == bases::vfwnmsac >+ || instance.base == bases::vfwnmacc || instance.base == bases::vfwmul >+ || instance.base == bases::vfcvt_x || instance.base == bases::vfcvt_f >+ || instance.base == bases::vfcvt_xu || instance.base == bases::vfwmsac >+ || instance.base == bases::vfwmacc || instance.base == bases::vfwcvt_x >+ || instance.base == bases::vfwadd || instance.base == bases::vfsub >+ || instance.base == bases::vfsqrt || instance.base == bases::vfredusum >+ || instance.base == bases::vfrsub || instance.base == bases::vfredosum >+ || instance.base == bases::vfrec7 || instance.base == bases::vfrdiv >+ || instance.base == bases::vfnmsub || instance.base == bases::vfnmsac >+ || instance.base == bases::vfnmadd || instance.base == bases::vfnmacc >+ || instance.base == bases::vfncvt_f || instance.base == bases::vfncvt_x >+ || instance.base == bases::vfncvt_xu || instance.base == bases::vfmul >+ || instance.base == bases::vfmsub || instance.base == bases::vfmsac >+ || instance.base == bases::vfmadd || instance.base == bases::vfmacc >+ || instance.base == bases::vfdiv || instance.base == bases::vfwcvt_xu; >+} >+ >+static bool >+maybe_require_vxrm_p (function_instance &instance) >+{ >+ return instance.base == bases::vaadd || instance.base == bases::vaaddu >+ || instance.base == bases::vasub || instance.base == bases::vasubu >+ || instance.base == bases::vssrl || instance.base == bases::vssra >+ || instance.base == bases::vsmul || instance.base == bases::vnclipu >+ || instance.base == bases::vnclip; >+} > >I am sorry that I didn't was wrong before. > >Could we add maybe_require_frm_p and maybe_require_vxrm_p into function_base ? >By default it is FALSE. > >In riscv-vector-builtins-bases.cc, set them in each corresponding function_base: > >For example: > >class vsmul :: public function_base >bool maybe_require_vxrm_p () const >{ > return true; >} > >The benefits is that you only need to use instance.base.maybe_require_frm_p () or instance.base.maybe_require_vxrm_p () >And no need to compare them one by one. > >Thanks. > > >juzhe.zhong@rivai.ai > >From: Li Xu >Date: 2023-10-31 10:24 >To: gcc-patches >CC: kito.cheng; palmer; juzhe.zhong; xuli >Subject: [PATCH V5] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic >From: xuli > >Update in v5: >* Split has_vxrm_or_frm_p into maybe_require_frm_p and > maybe_require_vxrm_p. >* Adjust comments. > >Update in v4: >* Remove class function_resolver. >* Remove function get_non_overloaded_instance. >* Add overloaded hash traits for non-overloaded intrinsic. >* All overloaded intrinsics are implemented, and the tests pass. > >Update in v3: > >* Rewrite comment for overloaded function add. >* Move get_non_overloaded_instance to function_base. > >Update in v2: > >* Add get_non_overloaded_instance for function instance. >* Fix overload check for policy function. >* Enrich the test cases check. > >Original log: > >This patch would like add the framework to support the RVV overloaded >intrinsic API in riscv-xxx-xxx-gcc, like riscv-xxx-xxx-g++ did. > >However, it almost leverage the hook TARGET_RESOLVE_OVERLOADED_BUILTIN >with below steps. > >* Register overloaded functions. >* Add function_resolver for overloaded function resolving. >* Add resolve API for function shape with default implementation. >* Implement HOOK for navigating the overloaded API to non-overloaded API. > >gcc/ChangeLog: > > * config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): New function for the hook. > (riscv_register_pragmas): Register the hook. > * config/riscv/riscv-protos.h (resolve_overloaded_builtin): New decl. > * config/riscv/riscv-vector-builtins-shapes.cc (build_one): Register overloaded function. > * config/riscv/riscv-vector-builtins.cc (struct non_overloaded_registered_function_hasher): > New hash table. > (function_builder::add_function): Add overloaded arg. > (function_builder::add_unique_function): Map overloaded function to non-overloaded function. > (function_builder::add_overloaded_function): New API impl. > (registered_function::overloaded_hash): Calculate hash value. > (maybe_require_frm_p): New function impl. > (maybe_require_vxrm_p): Ditto. > (has_vxrm_or_frm_p): Ditto. > (non_overloaded_registered_function_hasher::hash): Ditto. > (non_overloaded_registered_function_hasher::equal): Ditto. > (handle_pragma_vector): Allocate space for hash table. > (resolve_overloaded_builtin): New function impl. > * config/riscv/riscv-vector-builtins.h: Add additional parameters to add_function. > >gcc/testsuite/ChangeLog: > > * gcc.target/riscv/rvv/base/overloaded_rv32_vadd.c: New test. > * gcc.target/riscv/rvv/base/overloaded_rv32_vfadd.c: New test. > * gcc.target/riscv/rvv/base/overloaded_rv32_vget_vset.c: New test. > * gcc.target/riscv/rvv/base/overloaded_rv32_vloxseg2ei16.c: New test. > * gcc.target/riscv/rvv/base/overloaded_rv32_vmv.c: New test. > * gcc.target/riscv/rvv/base/overloaded_rv32_vreinterpret.c: New test. > * gcc.target/riscv/rvv/base/overloaded_rv64_vadd.c: New test. > * gcc.target/riscv/rvv/base/overloaded_rv64_vfadd.c: New test. > * gcc.target/riscv/rvv/base/overloaded_rv64_vget_vset.c: New test. > * gcc.target/riscv/rvv/base/overloaded_rv64_vloxseg2ei16.c: New test. > * gcc.target/riscv/rvv/base/overloaded_rv64_vmv.c: New test. > * gcc.target/riscv/rvv/base/overloaded_rv64_vreinterpret.c: New test. > * gcc.target/riscv/rvv/base/overloaded_vadd.h: New test. > * gcc.target/riscv/rvv/base/overloaded_vfadd.h: New test. > * gcc.target/riscv/rvv/base/overloaded_vget_vset.h: New test. > * gcc.target/riscv/rvv/base/overloaded_vloxseg2ei16.h: New test. > * gcc.target/riscv/rvv/base/overloaded_vmv.h: New test. > * gcc.target/riscv/rvv/base/overloaded_vreinterpret.h: New test. > >Signed-off-by: Li Xu >Co-Authored-By: Pan Li >--- >gcc/config/riscv/riscv-c.cc | 36 ++- >gcc/config/riscv/riscv-protos.h | 1 + >.../riscv/riscv-vector-builtins-shapes.cc | 1 + >gcc/config/riscv/riscv-vector-builtins.cc | 259 +++++++++++++++++- >gcc/config/riscv/riscv-vector-builtins.h | 5 +- >.../riscv/rvv/base/overloaded_rv32_vadd.c | 12 + >.../riscv/rvv/base/overloaded_rv32_vfadd.c | 12 + >.../rvv/base/overloaded_rv32_vget_vset.c | 7 + >.../rvv/base/overloaded_rv32_vloxseg2ei16.c | 11 + >.../riscv/rvv/base/overloaded_rv32_vmv.c | 10 + >.../rvv/base/overloaded_rv32_vreinterpret.c | 10 + >.../riscv/rvv/base/overloaded_rv64_vadd.c | 11 + >.../riscv/rvv/base/overloaded_rv64_vfadd.c | 11 + >.../rvv/base/overloaded_rv64_vget_vset.c | 6 + >.../rvv/base/overloaded_rv64_vloxseg2ei16.c | 10 + >.../riscv/rvv/base/overloaded_rv64_vmv.c | 10 + >.../rvv/base/overloaded_rv64_vreinterpret.c | 9 + >.../riscv/rvv/base/overloaded_vadd.h | 59 ++++ >.../riscv/rvv/base/overloaded_vfadd.h | 67 +++++ >.../riscv/rvv/base/overloaded_vget_vset.h | 27 ++ >.../riscv/rvv/base/overloaded_vloxseg2ei16.h | 39 +++ >.../riscv/rvv/base/overloaded_vmv.h | 26 ++ >.../riscv/rvv/base/overloaded_vreinterpret.h | 29 ++ >23 files changed, 659 insertions(+), 9 deletions(-) >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vadd.c >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vfadd.c >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vget_vset.c >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vloxseg2ei16.c >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vmv.c >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vreinterpret.c >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vadd.c >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vfadd.c >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vget_vset.c >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vloxseg2ei16.c >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vmv.c >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vreinterpret.c >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vadd.h >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vfadd.h >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vget_vset.h >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vloxseg2ei16.h >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vmv.h >create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vreinterpret.h > >diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc >index 283052ae313..bedf7217390 100644 >--- a/gcc/config/riscv/riscv-c.cc >+++ b/gcc/config/riscv/riscv-c.cc >@@ -215,16 +215,50 @@ riscv_check_builtin_call (location_t loc, vec arg_loc, tree fndecl, > case RISCV_BUILTIN_VECTOR: > return riscv_vector::check_builtin_call (loc, arg_loc, subcode, >- orig_fndecl, nargs, args); >+ fndecl, nargs, args); > } > gcc_unreachable (); >} >+/* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN. */ >+static tree >+riscv_resolve_overloaded_builtin (unsigned int uncast_location, tree fndecl, >+ void *uncast_arglist) >+{ >+ vec empty = {}; >+ location_t loc = (location_t) uncast_location; >+ vec *arglist = (vec *) uncast_arglist; >+ unsigned int code = DECL_MD_FUNCTION_CODE (fndecl); >+ unsigned int subcode = code >> RISCV_BUILTIN_SHIFT; >+ tree new_fndecl = NULL_TREE; >+ >+ if (!arglist) >+ arglist = ∅ >+ >+ switch (code & RISCV_BUILTIN_CLASS) >+ { >+ case RISCV_BUILTIN_GENERAL: >+ break; >+ case RISCV_BUILTIN_VECTOR: >+ new_fndecl = riscv_vector::resolve_overloaded_builtin (subcode, arglist); >+ break; >+ default: >+ gcc_unreachable (); >+ } >+ >+ if (new_fndecl == NULL_TREE) >+ return new_fndecl; >+ >+ return build_function_call_vec (loc, vNULL, new_fndecl, arglist, NULL, >+ fndecl); >+} >+ >/* Implement REGISTER_TARGET_PRAGMAS. */ >void >riscv_register_pragmas (void) >{ >+ targetm.resolve_overloaded_builtin = riscv_resolve_overloaded_builtin; > targetm.check_builtin_call = riscv_check_builtin_call; > c_register_pragma ("riscv", "intrinsic", riscv_pragma_intrinsic); >} >diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h >index 2926d5d50d5..5836333bc5d 100644 >--- a/gcc/config/riscv/riscv-protos.h >+++ b/gcc/config/riscv/riscv-protos.h >@@ -430,6 +430,7 @@ gimple *gimple_fold_builtin (unsigned int, gimple_stmt_iterator *, gcall *); >rtx expand_builtin (unsigned int, tree, rtx); >bool check_builtin_call (location_t, vec, unsigned int, > tree, unsigned int, tree *); >+tree resolve_overloaded_builtin (unsigned int, vec *); >bool const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT); >bool legitimize_move (rtx, rtx *); >void emit_vlmax_vsetvl (machine_mode, rtx); >diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc >index 0bda934ae16..ee570458ce9 100644 >--- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc >+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc >@@ -49,6 +49,7 @@ build_one (function_builder &b, const function_group_info &group, > group.ops_infos.types[vec_type_idx].index); > b.allocate_argument_types (function_instance, argument_types); > b.apply_predication (function_instance, return_type, argument_types); >+ b.add_overloaded_function (function_instance, *group.shape); > b.add_unique_function (function_instance, (*group.shape), return_type, >argument_types); >} >diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc >index 5d4dc264fa6..5c70f7a9c6c 100644 >--- a/gcc/config/riscv/riscv-vector-builtins.cc >+++ b/gcc/config/riscv/riscv-vector-builtins.cc >@@ -80,6 +80,32 @@ public: > /* The decl itself. */ > tree GTY ((skip)) decl; >+ >+ /* The overload hash of non-overloaded intrinsic is determined by >+ the overload name and argument list. Adding the overload name to >+ the hash is also to address the following situations: >+ vint16mf4_t __riscv_vreinterpret_i16mf4 (vfloat16mf4_t src); >+ vuint16mf4_t __riscv_vreinterpret_u16mf4 (vfloat16mf4_t src); >+ The base, shape and argument list of the vreinterpret instance are >+ the same, only the overload name is different. Therefore, it is >+ enough to add overload_name and argument list to the hash value.*/ >+ const char *overload_name; >+ >+ /* The argument list part of the hash value. Add the unsigned/signed type >+ and machine mode of each argument to the hash value. */ >+ vec GTY ((skip)) argument_types; >+ >+ /* True if the decl represents an overloaded function that needs to be >+ resolved. */ >+ bool overloaded_p; >+ >+ /* The hash value to indicate the non-overloaded function. Generate hash value >+ based on overload_name and argument_types. */ >+ hashval_t overloaded_hash () const; >+ >+ /* Generate hash value based on the overload_name and the argument list passed >+ by the user when calling. */ >+ hashval_t overloaded_hash (const vec &); >}; >/* Hash traits for registered_function. */ >@@ -91,6 +117,14 @@ struct registered_function_hasher : nofree_ptr_hash > static bool equal (value_type, const compare_type &); >}; >+/* Hash traits for overload registered_function. */ >+struct non_overloaded_registered_function_hasher >+ : nofree_ptr_hash >+{ >+ static hashval_t hash (value_type); >+ static bool equal (value_type, const compare_type &); >+}; >+ >/* Static information about each RVV type. */ >static CONSTEXPR const vector_type_info vector_types[] = { >#define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, ARGS...) \ >@@ -2611,6 +2645,12 @@ static GTY (()) vec *registered_functions; > overloaded functions. */ >static hash_table *function_table; >+/* All registered function decls, hashed on overload_name and argument list >+ of the registered_function. This is used for looking up implementations >+ of non-overloaded functions. */ >+static hash_table >+ *non_overloaded_function_table; >+ >/* RAII class for enabling enough RVV features to define the built-in > types and implement the riscv_vector.h pragma. >@@ -3369,7 +3409,9 @@ function_builder::get_attributes (const function_instance &instance) >registered_function & >function_builder::add_function (const function_instance &instance, >const char *name, tree fntype, tree attrs, >- bool placeholder_p) >+ bool placeholder_p, const char *overload_name, >+ const vec &argument_types, >+ bool overloaded_p = false) >{ > unsigned int code = vec_safe_length (registered_functions); > code = (code << RISCV_BUILTIN_SHIFT) + RISCV_BUILTIN_VECTOR; >@@ -3395,6 +3437,9 @@ function_builder::add_function (const function_instance &instance, > registered_function &rfn = *ggc_alloc (); > rfn.instance = instance; > rfn.decl = decl; >+ rfn.overload_name = overload_name ? xstrdup (overload_name) : NULL; >+ rfn.argument_types = argument_types; >+ rfn.overloaded_p = overloaded_p; > vec_safe_push (registered_functions, &rfn); > return rfn; >@@ -3415,6 +3460,10 @@ function_builder::add_unique_function (const function_instance &instance, > if (!check_required_extensions (instance)) > return; >+ /* Also add the function under its overloaded alias, if we want >+ a separate decl for each instance of an overloaded function. */ >+ char *overload_name = shape->get_name (*this, instance, true); >+ > /* Add the function under its full (unique) name. */ > char *name = shape->get_name (*this, instance, false); > tree fntype >@@ -3422,7 +3471,8 @@ function_builder::add_unique_function (const function_instance &instance, >argument_types.address ()); > tree attrs = get_attributes (instance); > registered_function &rfn >- = add_function (instance, name, fntype, attrs, false); >+ = add_function (instance, name, fntype, attrs, false, overload_name, >+ argument_types.copy ()); > /* Enter the function into the hash table. */ > hashval_t hash = instance.hash (); >@@ -3431,19 +3481,45 @@ function_builder::add_unique_function (const function_instance &instance, > gcc_assert (!*rfn_slot); > *rfn_slot = &rfn; >- /* Also add the function under its overloaded alias, if we want >- a separate decl for each instance of an overloaded function. */ >- char *overload_name = shape->get_name (*this, instance, true); > if (overload_name) > { > /* Attribute lists shouldn't be shared. */ > tree attrs = get_attributes (instance); > bool placeholder_p = !m_direct_overloads; >- add_function (instance, overload_name, fntype, attrs, placeholder_p); >+ add_function (instance, overload_name, fntype, attrs, placeholder_p, NULL, >+ vNULL); >+ >+ /* Enter the function into the non-overloaded hash table. */ >+ hash = rfn.overloaded_hash (); >+ rfn_slot = non_overloaded_function_table->find_slot_with_hash (&rfn, hash, >+ INSERT); >+ gcc_assert (!*rfn_slot); >+ *rfn_slot = &rfn; > } > obstack_free (&m_string_obstack, name); >} >+/* Add overloaded function for gcc. */ >+void >+function_builder::add_overloaded_function (const function_instance &instance, >+ const function_shape *shape) >+{ >+ if (!check_required_extensions (instance)) >+ return; >+ >+ char *name = shape->get_name (*this, instance, true); >+ >+ if (name) >+ { >+ /* To avoid API conflicting, take void return type and void argument >+ 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); >+ obstack_free (&m_string_obstack, name); >+ } >+} >+ >function_call_info::function_call_info (location_t location_in, >const function_instance &instance_in, >tree fndecl_in) >@@ -3991,6 +4067,155 @@ registered_function_hasher::equal (value_type value, const compare_type &key) > return value->instance == key; >} >+hashval_t >+registered_function::overloaded_hash () const >+{ >+ inchash::hash h; >+ tree type; >+ unsigned int unsigned_p, mode_p; >+ h.add (overload_name, strlen (overload_name)); >+ for (unsigned int i = 0; i < argument_types.length (); i++) >+ { >+ type = argument_types[i]; >+ unsigned_p = POINTER_TYPE_P (type) ? TYPE_UNSIGNED (TREE_TYPE (type)) >+ : TYPE_UNSIGNED (type); >+ mode_p = POINTER_TYPE_P (type) ? TYPE_MODE (TREE_TYPE (type)) >+ : TYPE_MODE (type); >+ h.add_int (unsigned_p); >+ h.add_int (mode_p); >+ } >+ >+ return h.end (); >+} >+ >+static bool >+maybe_require_frm_p (function_instance &instance) >+{ >+ return instance.base == bases::vfwredusum >+ || instance.base == bases::vfwredosum || instance.base == bases::vfadd >+ || instance.base == bases::vfwsub || instance.base == bases::vfwnmsac >+ || instance.base == bases::vfwnmacc || instance.base == bases::vfwmul >+ || instance.base == bases::vfcvt_x || instance.base == bases::vfcvt_f >+ || instance.base == bases::vfcvt_xu || instance.base == bases::vfwmsac >+ || instance.base == bases::vfwmacc || instance.base == bases::vfwcvt_x >+ || instance.base == bases::vfwadd || instance.base == bases::vfsub >+ || instance.base == bases::vfsqrt || instance.base == bases::vfredusum >+ || instance.base == bases::vfrsub || instance.base == bases::vfredosum >+ || instance.base == bases::vfrec7 || instance.base == bases::vfrdiv >+ || instance.base == bases::vfnmsub || instance.base == bases::vfnmsac >+ || instance.base == bases::vfnmadd || instance.base == bases::vfnmacc >+ || instance.base == bases::vfncvt_f || instance.base == bases::vfncvt_x >+ || instance.base == bases::vfncvt_xu || instance.base == bases::vfmul >+ || instance.base == bases::vfmsub || instance.base == bases::vfmsac >+ || instance.base == bases::vfmadd || instance.base == bases::vfmacc >+ || instance.base == bases::vfdiv || instance.base == bases::vfwcvt_xu; >+} >+ >+static bool >+maybe_require_vxrm_p (function_instance &instance) >+{ >+ return instance.base == bases::vaadd || instance.base == bases::vaaddu >+ || instance.base == bases::vasub || instance.base == bases::vasubu >+ || instance.base == bases::vssrl || instance.base == bases::vssra >+ || instance.base == bases::vsmul || instance.base == bases::vnclipu >+ || instance.base == bases::vnclip; >+} >+ >+bool >+has_vxrm_or_frm_p (function_instance &instance, const vec &arglist) >+{ >+ if (maybe_require_vxrm_p (instance) >+ || (maybe_require_frm_p (instance) >+ && (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2])) >+ == INTEGER_TYPE))) >+ return true; >+ return false; >+} >+ >+hashval_t >+registered_function::overloaded_hash (const vec &arglist) >+{ >+ argument_types = vNULL; >+ unsigned int len = arglist.length (); >+ >+ for (unsigned int i = 0; i < len; i++) >+ { >+ /* vint8m1_t __riscv_vget_i8m1(vint8m2_t src, size_t index); >+ When the user calls vget intrinsic, the __riscv_vget_i8m1(src, 1) >+ form is used. The compiler recognizes that the parameter index is signed >+ int, which is inconsistent with size_t, so the index is converted to >+ size_t type in order to get correct hash value. vint8m2_t >+ __riscv_vset(vint8m2_t dest, size_t index, vint8m1_t value); The reason >+ is the same as above. */ >+ if ((instance.base == bases::vget && (i == (len - 1))) >+ || (instance.base == bases::vset && (i == (len - 2)))) >+ argument_types.safe_push (size_type_node); >+ /* Vector fixed-point arithmetic instructions requiring argument vxrm. >+ For example: vuint32m4_t __riscv_vaaddu(vuint32m4_t vs2, >+ vuint32m4_t vs1, unsigned int vxrm, size_t vl); The user calls vaaddu >+ intrinsic in the form of __riscv_vaaddu(vs2, vs1, 2, vl). The compiler >+ recognizes that the parameter vxrm is a signed int, which is inconsistent >+ with the parameter unsigned int vxrm declared by intrinsic, so the >+ parameter vxrm is converted to an unsigned int type in order to get >+ correct hash value. >+ >+ Vector Floating-Point Instructions requiring argument frm. >+ DEF_RVV_FUNCTION (vfadd, alu, full_preds, f_vvv_ops) >+ DEF_RVV_FUNCTION (vfadd_frm, alu_frm, full_preds, f_vvv_ops) >+ Taking vfadd as an example, theoretically we can add base or shape to the >+ hash value to distinguish whether the frm parameter is required. >+ vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl); >+ vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned int >+ frm, size_t vl); >+ >+ However, the current registration mechanism of overloaded intinsic for gcc >+ limits the intrinsic obtained by entering the hook to always be vfadd, not >+ vfadd_frm. Therefore, the correct hash value cannot be obtained through the >+ parameter list and overload name, base or shape. >+ +--------+---------------------------+-------------------+ >+ | index | name | kind | >+ +--------+---------------------------+-------------------+ >+ | 124733 | __riscv_vfadd | Overloaded | <- Hook fun code >+ +--------+---------------------------+-------------------+ >+ | 124735 | __riscv_vfadd_vv_f32m1 | Non-overloaded | >+ +--------+---------------------------+-------------------+ >+ | 124737 | __riscv_vfadd | Placeholder | >+ +--------+---------------------------+-------------------+ >+ | ... | >+ +--------+---------------------------+-------------------+ >+ | ... | >+ +--------+---------------------------+-------------------+ >+ | 125739 | __riscv_vfadd | Overloaded | >+ +--------+---------------------------+-------------------+ >+ | 125741 | __riscv_vfadd_vv_f32m1_rm | Non-overloaded | >+ +--------+---------------------------+-------------------+ >+ | 125743 | __riscv_vfadd | Placeholder | >+ +--------+---------------------------+-------------------+ >+ >+ Therefore, the hash value cannot be added with base or shape, and needs >+ to be distinguished by whether the penultimate parameter is INTEGER_TYPE. */ >+ else if (has_vxrm_or_frm_p (instance, arglist) && (i == (len - 2))) >+ argument_types.safe_push (unsigned_type_node); >+ else >+ argument_types.safe_push (TREE_TYPE (arglist[i])); >+ } >+ return overloaded_hash (); >+} >+ >+inline hashval_t >+non_overloaded_registered_function_hasher::hash (value_type value) >+{ >+ return value->overloaded_hash (); >+} >+ >+inline bool >+non_overloaded_registered_function_hasher::equal (value_type value, >+ const compare_type &key) >+{ >+ return ((strcmp (value->overload_name, key->overload_name) == 0) >+ && value->overloaded_hash () == key->overloaded_hash ()); >+} >+ >/* If TYPE is a built-in type defined by the RVV ABI, return the mangled name, > otherwise return NULL. */ >const char * >@@ -4139,7 +4364,7 @@ register_frm () >void >handle_pragma_vector () >{ >- if (function_table) >+ if (function_table || non_overloaded_function_table) > { > error ("duplicate definition of %qs", "riscv_vector.h"); > return; >@@ -4156,6 +4381,8 @@ handle_pragma_vector () > /* Define the functions. */ > function_table = new hash_table (1023); >+ non_overloaded_function_table >+ = new hash_table (1023); > function_builder builder; > for (unsigned int i = 0; i < ARRAY_SIZE (function_groups); ++i) > builder.register_function_group (function_groups[i]); >@@ -4208,6 +4435,24 @@ check_builtin_call (location_t location, vec, unsigned int code, > TREE_TYPE (rfn.decl), nargs, args).check (); >} >+tree >+resolve_overloaded_builtin (unsigned int code, vec *arglist) >+{ >+ if (code >= vec_safe_length (registered_functions)) >+ return NULL_TREE; >+ >+ registered_function *rfun = (*registered_functions)[code]; >+ >+ if (!rfun || !rfun->overloaded_p) >+ return NULL_TREE; >+ >+ hashval_t hash = rfun->overloaded_hash (*arglist); >+ registered_function *rfn >+ = non_overloaded_function_table->find_with_hash (rfun, hash); >+ gcc_assert (rfn); >+ return rfn->decl; >+} >+ >function_instance >get_read_vl_instance (void) >{ >diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h >index e358a8e4d91..4f41e880ac3 100644 >--- a/gcc/config/riscv/riscv-vector-builtins.h >+++ b/gcc/config/riscv/riscv-vector-builtins.h >@@ -277,6 +277,8 @@ public: > void apply_predication (const function_instance &, tree, vec &) const; > void add_unique_function (const function_instance &, const function_shape *, > tree, vec &); >+ void add_overloaded_function (const function_instance &, >+ const function_shape *); > void register_function_group (const function_group_info &); > void append_name (const char *); > void append_base_name (const char *); >@@ -288,7 +290,8 @@ private: > tree get_attributes (const function_instance &); > registered_function &add_function (const function_instance &, const char *, >- tree, tree, bool); >+ tree, tree, bool, const char *, >+ const vec &, 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/overloaded_rv32_vadd.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vadd.c >new file mode 100644 >index 00000000000..5f10aa9bf35 >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vadd.c >@@ -0,0 +1,12 @@ >+/* { dg-do compile } */ >+/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ >+ >+#include "overloaded_vadd.h" >+ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*ta,\s*ma} 4 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 8 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*tu,\s*ma} 4 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*ta,\s*mu} 2 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*tu,\s*mu} 2 } } */ >+/* { dg-final { scan-assembler-times {vadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 6 } } */ >+/* { dg-final { scan-assembler-times {vadd\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[ax][0-9]+} 6 } } */ >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vfadd.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vfadd.c >new file mode 100644 >index 00000000000..bea35a13a7b >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vfadd.c >@@ -0,0 +1,12 @@ >+/* { dg-do compile } */ >+/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ >+ >+#include "overloaded_vfadd.h" >+ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e16,\s*mf4,\s*ta,\s*ma} 16 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*ta,\s*ma} 4 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 8 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*tu,\s*ma} 4 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*tu,\s*mu} 2 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*ta,\s*mu} 2 } } */ >+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 12 } } */ >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vget_vset.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vget_vset.c >new file mode 100644 >index 00000000000..6b0ba142b90 >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vget_vset.c >@@ -0,0 +1,7 @@ >+/* { dg-do compile } */ >+/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ >+ >+#include "overloaded_vget_vset.h" >+ >+/* { dg-final { scan-assembler-times {vl[0-9]+re[0-9]+\.v\s+v[0-9]+,\s*0\([ax][0-9]+\)} 14 } } */ >+/* { dg-final { scan-assembler-times {vs[0-9]+r\.v\s+v[0-9]+,\s*0\([ax][0-9]+\)} 13 } } */ >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vloxseg2ei16.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vloxseg2ei16.c >new file mode 100644 >index 00000000000..a20e4a3bb4f >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vloxseg2ei16.c >@@ -0,0 +1,11 @@ >+/* { dg-do compile } */ >+/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ >+ >+#include "overloaded_vloxseg2ei16.h" >+ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*ta,\s*ma} 2 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 4 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*tu,\s*ma} 2 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*tu,\s*mu} 1 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*ta,\s*mu} 1 } } */ >+/* { dg-final { scan-assembler-times {vloxseg2ei16\.v\s+v[0-9]+,\s*\([ax][0-9]+\),\s*v[0-9]+} 6 } } */ >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vmv.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vmv.c >new file mode 100644 >index 00000000000..237b34dbe91 >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vmv.c >@@ -0,0 +1,10 @@ >+/* { dg-do compile } */ >+/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ >+ >+#include "overloaded_vmv.h" >+ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*tu,\s*ma} 2 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*m1,\s*ta,\s*ma} 1 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*m1,\s*tu,\s*ma} 1 } } */ >+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*0,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */ >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vreinterpret.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vreinterpret.c >new file mode 100644 >index 00000000000..42d50589246 >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv32_vreinterpret.c >@@ -0,0 +1,10 @@ >+/* { dg-do compile } */ >+/* { dg-options "-march=rv32gcv_zvfh -mabi=ilp32 -O3 -Wno-psabi" } */ >+ >+#include "overloaded_vreinterpret.h" >+ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e16,\s*mf2,\s*ta,\s*ma} 2 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e32,\s*mf2,\s*ta,\s*ma} 1 } } */ >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vadd.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vadd.c >new file mode 100644 >index 00000000000..c4555e3f477 >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vadd.c >@@ -0,0 +1,11 @@ >+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ >+ >+#include "overloaded_vadd.h" >+ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*ta,\s*ma} 4 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 8 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*tu,\s*ma} 4 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*ta,\s*mu} 2 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*tu,\s*mu} 2 } } */ >+/* { dg-final { scan-assembler-times {vadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 6 } } */ >+/* { dg-final { scan-assembler-times {vadd\.vx\s+v[0-9]+,\s*v[0-9]+,\s*[ax][0-9]+} 6 } } */ >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vfadd.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vfadd.c >new file mode 100644 >index 00000000000..ca98136ce9b >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vfadd.c >@@ -0,0 +1,11 @@ >+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ >+ >+#include "overloaded_vfadd.h" >+ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e16,\s*mf4,\s*ta,\s*ma} 16 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*ta,\s*ma} 4 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 8 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*tu,\s*ma} 4 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*tu,\s*mu} 2 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*mf4,\s*ta,\s*mu} 2 } } */ >+/* { dg-final { scan-assembler-times {vfadd\.vv\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 12 } } */ >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vget_vset.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vget_vset.c >new file mode 100644 >index 00000000000..1cb4225084c >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vget_vset.c >@@ -0,0 +1,6 @@ >+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ >+ >+#include "overloaded_vget_vset.h" >+ >+/* { dg-final { scan-assembler-times {vl[0-9]+re[0-9]+\.v\s+v[0-9]+,\s*0\([ax][0-9]+\)} 14 } } */ >+/* { dg-final { scan-assembler-times {vs[0-9]+r\.v\s+v[0-9]+,\s*0\([ax][0-9]+\)} 13 } } */ >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vloxseg2ei16.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vloxseg2ei16.c >new file mode 100644 >index 00000000000..ea73170444d >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vloxseg2ei16.c >@@ -0,0 +1,10 @@ >+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ >+ >+#include "overloaded_vloxseg2ei16.h" >+ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*ta,\s*ma} 2 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 4 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*tu,\s*ma} 2 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*tu,\s*mu} 1 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e64,\s*m4,\s*ta,\s*mu} 1 } } */ >+/* { dg-final { scan-assembler-times {vloxseg2ei16\.v\s+v[0-9]+,\s*\([ax][0-9]+\),\s*v[0-9]+} 6 } } */ >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vmv.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vmv.c >new file mode 100644 >index 00000000000..c5da6bbfca8 >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vmv.c >@@ -0,0 +1,10 @@ >+/* { dg-do compile } */ >+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ >+ >+#include "overloaded_vmv.h" >+ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e8,\s*m1,\s*tu,\s*ma} 2 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*m1,\s*ta,\s*ma} 1 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[ax][0-9]+,\s*e16,\s*m1,\s*tu,\s*ma} 1 } } */ >+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*0,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */ >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vreinterpret.c b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vreinterpret.c >new file mode 100644 >index 00000000000..3b8399c126d >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_rv64_vreinterpret.c >@@ -0,0 +1,9 @@ >+/* { dg-options "-march=rv64gcv_zvfh -mabi=lp64 -O3 -Wno-psabi" } */ >+ >+#include "overloaded_vreinterpret.h" >+ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e16,\s*mf2,\s*ta,\s*ma} 2 } } */ >+/* { dg-final { scan-assembler-times {vsetvli\s+[ax][0-9]+,\s*zero,\s*e32,\s*mf2,\s*ta,\s*ma} 1 } } */ >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vadd.h b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vadd.h >new file mode 100644 >index 00000000000..3b41cff1b62 >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vadd.h >@@ -0,0 +1,59 @@ >+#include "riscv_vector.h" >+ >+vint8m1_t test_vadd_vv_i8m1(vint8m1_t vs2, vint8m1_t vs1, size_t vl) { >+ return __riscv_vadd(vs2, vs1, vl); >+} >+ >+vint8m1_t test_vadd_vx_i8m1(vint8m1_t vs2, int8_t rs1, size_t vl) { >+ return __riscv_vadd(vs2, rs1, vl); >+} >+ >+vint8m1_t test_vadd_vv_i8m1_m(vbool8_t vm, vint8m1_t vs2, vint8m1_t vs1, >+ size_t vl) { >+ return __riscv_vadd(vm, vs2, vs1, vl); >+} >+ >+vint8m1_t test_vadd_vx_i8m1_m(vbool8_t vm, vint8m1_t vs2, int8_t rs1, >+ size_t vl) { >+ return __riscv_vadd(vm, vs2, rs1, vl); >+} >+ >+vint8m1_t test_vadd_vv_i8m1_tu(vint8m1_t vd, vint8m1_t vs2, vint8m1_t vs1, >+ size_t vl) { >+ return __riscv_vadd_tu(vd, vs2, vs1, vl); >+} >+ >+vint8m1_t test_vadd_vx_i8m1_tu(vint8m1_t vd, vint8m1_t vs2, int8_t rs1, >+ size_t vl) { >+ return __riscv_vadd_tu(vd, vs2, rs1, vl); >+} >+ >+vint8m1_t test_vadd_vv_i8m1_tum(vbool8_t vm, vint8m1_t vd, vint8m1_t vs2, >+ vint8m1_t vs1, size_t vl) { >+ return __riscv_vadd_tum(vm, vd, vs2, vs1, vl); >+} >+ >+vint8m1_t test_vadd_vx_i8m1_tum(vbool8_t vm, vint8m1_t vd, vint8m1_t vs2, >+ int8_t rs1, size_t vl) { >+ return __riscv_vadd_tum(vm, vd, vs2, rs1, vl); >+} >+ >+vint8m1_t test_vadd_vv_i8m1_mu(vbool8_t vm, vint8m1_t vd, vint8m1_t vs2, >+ vint8m1_t vs1, size_t vl) { >+ return __riscv_vadd_mu(vm, vd, vs2, vs1, vl); >+} >+ >+vint8m1_t test_vadd_vx_i8m1_mu(vbool8_t vm, vint8m1_t vd, vint8m1_t vs2, >+ int8_t rs1, size_t vl) { >+ return __riscv_vadd_mu(vm, vd, vs2, rs1, vl); >+} >+ >+vint8m1_t test_vadd_vv_i8m1_tumu(vbool8_t vm, vint8m1_t vd, vint8m1_t vs2, >+ vint8m1_t vs1, size_t vl) { >+ return __riscv_vadd_tumu(vm, vd, vs2, vs1, vl); >+} >+ >+vint8m1_t test_vadd_vx_i8m1_tumu(vbool8_t vm, vint8m1_t vd, vint8m1_t vs2, >+ int8_t rs1, size_t vl) { >+ return __riscv_vadd_tumu(vm, vd, vs2, rs1, vl); >+} >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vfadd.h b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vfadd.h >new file mode 100644 >index 00000000000..798af420f2d >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vfadd.h >@@ -0,0 +1,67 @@ >+#include "riscv_vector.h" >+ >+vfloat16mf4_t test_vfadd_vv_f16mf4(vfloat16mf4_t vs2, vfloat16mf4_t vs1, >+ size_t vl) { >+ return __riscv_vfadd(vs2, vs1, vl); >+} >+ >+vfloat16mf4_t test_vfadd_vv_f16mf4_m(vbool64_t vm, vfloat16mf4_t vs2, >+ vfloat16mf4_t vs1, size_t vl) { >+ return __riscv_vfadd(vm, vs2, vs1, vl); >+} >+ >+vfloat16mf4_t test_vfadd_vv_f16mf4_tu(vfloat16mf4_t vd, vfloat16mf4_t vs2, >+ vfloat16mf4_t vs1, size_t vl) { >+ return __riscv_vfadd_tu(vd, vs2, vs1, vl); >+} >+ >+vfloat16mf4_t test_vfadd_vv_f16mf4_tum(vbool64_t vm, vfloat16mf4_t vd, >+ vfloat16mf4_t vs2, vfloat16mf4_t vs1, >+ size_t vl) { >+ return __riscv_vfadd_tum(vm, vd, vs2, vs1, vl); >+} >+ >+vfloat16mf4_t test_vfadd_vv_f16mf4_tumu(vbool64_t vm, vfloat16mf4_t vd, >+ vfloat16mf4_t vs2, vfloat16mf4_t vs1, >+ size_t vl) { >+ return __riscv_vfadd_tumu(vm, vd, vs2, vs1, vl); >+} >+ >+vfloat16mf4_t test_vfadd_vv_f16mf4_mu(vbool64_t vm, vfloat16mf4_t vd, >+ vfloat16mf4_t vs2, vfloat16mf4_t vs1, >+ size_t vl) { >+ return __riscv_vfadd_mu(vm, vd, vs2, vs1, vl); >+} >+ >+vfloat16mf4_t test_vfadd_vv_f16mf4_rm(vfloat16mf4_t vs2, vfloat16mf4_t vs1, >+ size_t vl) { >+ return __riscv_vfadd(vs2, vs1, __RISCV_FRM_RNE, vl); >+} >+ >+vfloat16mf4_t test_vfadd_vv_f16mf4_rm_m(vbool64_t vm, vfloat16mf4_t vs2, >+ vfloat16mf4_t vs1, size_t vl) { >+ return __riscv_vfadd(vm, vs2, vs1, __RISCV_FRM_RNE, vl); >+} >+ >+vfloat16mf4_t test_vfadd_vv_f16mf4_rm_tu(vfloat16mf4_t vd, vfloat16mf4_t vs2, >+ vfloat16mf4_t vs1, size_t vl) { >+ return __riscv_vfadd_tu(vd, vs2, vs1, __RISCV_FRM_RNE, vl); >+} >+ >+vfloat16mf4_t test_vfadd_vv_f16mf4_rm_tum(vbool64_t vm, vfloat16mf4_t vd, >+ vfloat16mf4_t vs2, vfloat16mf4_t vs1, >+ size_t vl) { >+ return __riscv_vfadd_tum(vm, vd, vs2, vs1, __RISCV_FRM_RNE, vl); >+} >+ >+vfloat16mf4_t test_vfadd_vv_f16mf4_rm_tumu(vbool64_t vm, vfloat16mf4_t vd, >+ vfloat16mf4_t vs2, vfloat16mf4_t vs1, >+ size_t vl) { >+ return __riscv_vfadd_tumu(vm, vd, vs2, vs1, __RISCV_FRM_RNE, vl); >+} >+ >+vfloat16mf4_t test_vfadd_vv_f16mf4_rm_mu(vbool64_t vm, vfloat16mf4_t vd, >+ vfloat16mf4_t vs2, vfloat16mf4_t vs1, >+ size_t vl) { >+ return __riscv_vfadd_mu(vm, vd, vs2, vs1, __RISCV_FRM_RNE, vl); >+} >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vget_vset.h b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vget_vset.h >new file mode 100644 >index 00000000000..01e072eb38f >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vget_vset.h >@@ -0,0 +1,27 @@ >+#include "riscv_vector.h" >+ >+vfloat16m1_t test_vget_v_f16m2_f16m1(vfloat16m2_t src, size_t index) { >+ return __riscv_vget_f16m1(src, 0); >+} >+ >+vint64m1_t test_vget_v_i64m4_i64m1(vint64m4_t src, size_t index) { >+ return __riscv_vget_i64m1(src, 0); >+} >+ >+vfloat16m1_t test_vget_v_f16m1x4_f16m1(vfloat16m1x4_t src, size_t index) { >+ return __riscv_vget_f16m1(src, 0); >+} >+ >+vint8m2_t test_vget_v_i8m2x3_i8m2(vint8m2x3_t src, size_t index) { >+ return __riscv_vget_i8m2(src, 0); >+} >+ >+vfloat16m2_t test_vset_v_f16m1_f16m2(vfloat16m2_t dest, size_t index, >+ vfloat16m1_t value) { >+ return __riscv_vset(dest, 0, value); >+} >+ >+vfloat64m1x7_t test_vset_v_f64m1_f64m1x7(vfloat64m1x7_t dest, size_t index, >+ vfloat64m1_t value) { >+ return __riscv_vset(dest, 0, value); >+} >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vloxseg2ei16.h b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vloxseg2ei16.h >new file mode 100644 >index 00000000000..2ebcdb41795 >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vloxseg2ei16.h >@@ -0,0 +1,39 @@ >+#include "riscv_vector.h" >+ >+typedef _Float16 float16_t; >+typedef float float32_t; >+typedef double float64_t; >+ >+vfloat64m4x2_t test_vloxseg2ei16_v_f64m4x2(const float64_t *rs1, >+ vuint16m1_t rs2, size_t vl) { >+ return __riscv_vloxseg2ei16(rs1, rs2, vl); >+} >+ >+vfloat64m4x2_t test_vloxseg2ei16_v_f64m4x2_m(vbool16_t vm, const float64_t *rs1, >+ vuint16m1_t rs2, size_t vl) { >+ return __riscv_vloxseg2ei16(vm, rs1, rs2, vl); >+} >+ >+vfloat64m4x2_t test_vloxseg2ei16_v_f64m4x2_tum(vbool16_t vm, vfloat64m4x2_t vd, >+ const float64_t *rs1, >+ vuint16m1_t rs2, size_t vl) { >+ return __riscv_vloxseg2ei16_tum(vm, vd, rs1, rs2, vl); >+} >+ >+vfloat64m4x2_t test_vloxseg2ei16_v_f64m4x2_tumu(vbool16_t vm, vfloat64m4x2_t vd, >+ const float64_t *rs1, >+ vuint16m1_t rs2, size_t vl) { >+ return __riscv_vloxseg2ei16_tumu(vm, vd, rs1, rs2, vl); >+} >+ >+vfloat64m4x2_t test_vloxseg2ei16_v_f64m4x2_mu(vbool16_t vm, vfloat64m4x2_t vd, >+ const float64_t *rs1, >+ vuint16m1_t rs2, size_t vl) { >+ return __riscv_vloxseg2ei16_mu(vm, vd, rs1, rs2, vl); >+} >+ >+vfloat64m4x2_t test_vloxseg2ei16_v_f64m4x2_tu(vfloat64m4x2_t vd, >+ const float64_t *rs1, >+ vuint16m1_t rs2, size_t vl) { >+ return __riscv_vloxseg2ei16_tu(vd, rs1, rs2, vl); >+} >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vmv.h b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vmv.h >new file mode 100644 >index 00000000000..fd3f1d28c0a >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vmv.h >@@ -0,0 +1,26 @@ >+#include "riscv_vector.h" >+ >+vint8m1_t test_vmv_v_v_i8m1 (vint8m1_t vs1, size_t vl) { >+ return __riscv_vmv_v (vs1, vl); >+} >+ >+vint8m1_t test_vmv_v_v_i8m1_tu (vint8m1_t vd, vint8m1_t vs1, size_t vl) { >+ return __riscv_vmv_v_tu(vd, vs1, vl); >+} >+ >+vfloat16m1_t test_vmv_v_v_f16m1 (vfloat16m1_t vs1, size_t vl) { >+ return __riscv_vmv_v (vs1, vl); >+} >+ >+vfloat16m1_t test_vmv_v_v_f16m1_tu (vfloat16m1_t vd, vfloat16m1_t vs1, >+ size_t vl) { >+ return __riscv_vmv_v_tu (vd, vs1, vl); >+} >+ >+int8_t test_vmv_x_s_i8m1_i8(vint8m1_t vs1) { >+ return __riscv_vmv_x (vs1); >+} >+ >+vint8m1_t test_vmv_s_x_i8m1_tu(vint8m1_t vd, int8_t rs1, size_t vl) { >+ return __riscv_vmv_s_tu(vd, rs1, vl); >+} >diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vreinterpret.h b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vreinterpret.h >new file mode 100644 >index 00000000000..904b0ceee72 >--- /dev/null >+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/overloaded_vreinterpret.h >@@ -0,0 +1,29 @@ >+#include "riscv_vector.h" >+ >+vuint16m1_t test_vreinterpret_v_b2_u16m1(vbool2_t src) { >+ return __riscv_vreinterpret_u16m1(src); >+} >+ >+vbool4_t test_vreinterpret_v_i32m1_b4(vint32m1_t src) { >+ return __riscv_vreinterpret_b4(src); >+} >+ >+vint8mf2_t test_vreinterpret_v_i16mf2_i8mf2(vint16mf2_t src) { >+ return __riscv_vreinterpret_i8mf2(src); >+} >+ >+vint32mf2_t test_vreinterpret_v_i16mf2_i32mf2(vint16mf2_t src) { >+ return __riscv_vreinterpret_i32mf2(src); >+} >+ >+vint32m1_t test_vreinterpret_v_i16m1_i32m1(vint16m1_t src) { >+ return __riscv_vreinterpret_i32m1(src); >+} >+ >+vint8m4_t test_vreinterpret_v_i32m4_i8m4(vint32m4_t src) { >+ return __riscv_vreinterpret_i8m4(src); >+} >+ >+vuint8m8_t test_vreinterpret_v_u32m8_u8m8(vuint32m8_t src) { >+ return __riscv_vreinterpret_u8m8(src); >+} >-- >2.17.1 > >