[V5] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
Checks
Commit Message
From: xuli <xuli1@eswincomputing.com>
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 <xuli1@eswincomputing.com>
Co-Authored-By: Pan Li <pan2.li@intel.com>
---
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
Comments
+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 <xuli1@eswincomputing.com>
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 <xuli1@eswincomputing.com>
Co-Authored-By: Pan Li <pan2.li@intel.com>
---
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<location_t> 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<tree, va_gc> empty = {};
+ location_t loc = (location_t) uncast_location;
+ vec<tree, va_gc> *arglist = (vec<tree, va_gc> *) 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<location_t>, unsigned int,
tree, unsigned int, tree *);
+tree resolve_overloaded_builtin (unsigned int, vec<tree, va_gc> *);
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<tree> 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<tree, va_gc> &);
};
/* Hash traits for registered_function. */
@@ -91,6 +117,14 @@ struct registered_function_hasher : nofree_ptr_hash<registered_function>
static bool equal (value_type, const compare_type &);
};
+/* Hash traits for overload registered_function. */
+struct non_overloaded_registered_function_hasher
+ : nofree_ptr_hash<registered_function>
+{
+ 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_function *, va_gc> *registered_functions;
overloaded functions. */
static hash_table<registered_function_hasher> *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_registered_function_hasher>
+ *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<tree> &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<registered_function> ();
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<tree, va_gc> &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<tree, va_gc> &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<registered_function_hasher> (1023);
+ non_overloaded_function_table
+ = new hash_table<non_overloaded_registered_function_hasher> (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<location_t>, unsigned int code,
TREE_TYPE (rfn.decl), nargs, args).check ();
}
+tree
+resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *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<tree> &) const;
void add_unique_function (const function_instance &, const function_shape *,
tree, vec<tree> &);
+ 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<tree> &, 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
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<PLUS> vadd_obj;
static CONSTEXPR const binop<PLUS> vfadd_obj;
static CONSTEXPR const binop<PLUS, HAS_FRM> vfadd_frm_obj;
template<rtx_code CODE, enum frm_op_type FRM_OP = NO_FRM>
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 <xuli1@eswincomputing.com>
>
>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 <xuli1@eswincomputing.com>
>Co-Authored-By: Pan Li <pan2.li@intel.com>
>---
>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<location_t> 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<tree, va_gc> empty = {};
>+ location_t loc = (location_t) uncast_location;
>+ vec<tree, va_gc> *arglist = (vec<tree, va_gc> *) 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<location_t>, unsigned int,
> tree, unsigned int, tree *);
>+tree resolve_overloaded_builtin (unsigned int, vec<tree, va_gc> *);
>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<tree> 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<tree, va_gc> &);
>};
>/* Hash traits for registered_function. */
>@@ -91,6 +117,14 @@ struct registered_function_hasher : nofree_ptr_hash<registered_function>
> static bool equal (value_type, const compare_type &);
>};
>+/* Hash traits for overload registered_function. */
>+struct non_overloaded_registered_function_hasher
>+ : nofree_ptr_hash<registered_function>
>+{
>+ 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_function *, va_gc> *registered_functions;
> overloaded functions. */
>static hash_table<registered_function_hasher> *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_registered_function_hasher>
>+ *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<tree> &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<registered_function> ();
> 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<tree, va_gc> &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<tree, va_gc> &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<registered_function_hasher> (1023);
>+ non_overloaded_function_table
>+ = new hash_table<non_overloaded_registered_function_hasher> (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<location_t>, unsigned int code,
> TREE_TYPE (rfn.decl), nargs, args).check ();
>}
>+tree
>+resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *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<tree> &) const;
> void add_unique_function (const function_instance &, const function_shape *,
> tree, vec<tree> &);
>+ 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<tree> &, 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
>
>
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<PLUS> vadd_obj;
static CONSTEXPR const binop<PLUS> vfadd_obj;
static CONSTEXPR const binop<PLUS, HAS_FRM> vfadd_frm_obj;
template<rtx_code CODE, enum frm_op_type FRM_OP = NO_FRM>
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 <xuli1@eswincomputing.com>
>
>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 <xuli1@eswincomputing.com>
>Co-Authored-By: Pan Li <pan2.li@intel.com>
>---
>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<location_t> 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<tree, va_gc> empty = {};
>+ location_t loc = (location_t) uncast_location;
>+ vec<tree, va_gc> *arglist = (vec<tree, va_gc> *) 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<location_t>, unsigned int,
> tree, unsigned int, tree *);
>+tree resolve_overloaded_builtin (unsigned int, vec<tree, va_gc> *);
>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<tree> 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<tree, va_gc> &);
>};
>/* Hash traits for registered_function. */
>@@ -91,6 +117,14 @@ struct registered_function_hasher : nofree_ptr_hash<registered_function>
> static bool equal (value_type, const compare_type &);
>};
>+/* Hash traits for overload registered_function. */
>+struct non_overloaded_registered_function_hasher
>+ : nofree_ptr_hash<registered_function>
>+{
>+ 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_function *, va_gc> *registered_functions;
> overloaded functions. */
>static hash_table<registered_function_hasher> *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_registered_function_hasher>
>+ *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<tree> &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<registered_function> ();
> 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<tree, va_gc> &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<tree, va_gc> &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<registered_function_hasher> (1023);
>+ non_overloaded_function_table
>+ = new hash_table<non_overloaded_registered_function_hasher> (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<location_t>, unsigned int code,
> TREE_TYPE (rfn.decl), nargs, args).check ();
>}
>+tree
>+resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *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<tree> &) const;
> void add_unique_function (const function_instance &, const function_shape *,
> tree, vec<tree> &);
>+ 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<tree> &, 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
>
>
@@ -215,16 +215,50 @@ riscv_check_builtin_call (location_t loc, vec<location_t> 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<tree, va_gc> empty = {};
+ location_t loc = (location_t) uncast_location;
+ vec<tree, va_gc> *arglist = (vec<tree, va_gc> *) 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);
}
@@ -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<location_t>, unsigned int,
tree, unsigned int, tree *);
+tree resolve_overloaded_builtin (unsigned int, vec<tree, va_gc> *);
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);
@@ -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);
}
@@ -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<tree> 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<tree, va_gc> &);
};
/* Hash traits for registered_function. */
@@ -91,6 +117,14 @@ struct registered_function_hasher : nofree_ptr_hash<registered_function>
static bool equal (value_type, const compare_type &);
};
+/* Hash traits for overload registered_function. */
+struct non_overloaded_registered_function_hasher
+ : nofree_ptr_hash<registered_function>
+{
+ 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_function *, va_gc> *registered_functions;
overloaded functions. */
static hash_table<registered_function_hasher> *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_registered_function_hasher>
+ *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<tree> &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<registered_function> ();
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<tree, va_gc> &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<tree, va_gc> &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<registered_function_hasher> (1023);
+ non_overloaded_function_table
+ = new hash_table<non_overloaded_registered_function_hasher> (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<location_t>, unsigned int code,
TREE_TYPE (rfn.decl), nargs, args).check ();
}
+tree
+resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *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)
{
@@ -277,6 +277,8 @@ public:
void apply_predication (const function_instance &, tree, vec<tree> &) const;
void add_unique_function (const function_instance &, const function_shape *,
tree, vec<tree> &);
+ 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<tree> &, bool);
/* True if we should create a separate decl for each instance of an
overloaded function, instead of using function_builder. */
new file mode 100644
@@ -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 } } */
new file mode 100644
@@ -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 } } */
new file mode 100644
@@ -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 } } */
new file mode 100644
@@ -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 } } */
new file mode 100644
@@ -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 } } */
new file mode 100644
@@ -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 } } */
new file mode 100644
@@ -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 } } */
new file mode 100644
@@ -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 } } */
new file mode 100644
@@ -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 } } */
new file mode 100644
@@ -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 } } */
new file mode 100644
@@ -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 } } */
new file mode 100644
@@ -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 } } */
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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);
+}