[V4] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
Checks
Commit Message
From: xuli <xuli1@eswincomputing.com>
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.
We validated this framework by the vmv_v intrinsic API(s), and we will
add more intrins API support in the underlying patches.
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.
(has_vxrm_or_frm_p): New function impl.
(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 | 255 +++++++++++++++++-
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, 653 insertions(+), 11 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
Thanks.
I like this 'HASH' solution which is much more reasonable to me.
Some comments here:
+bool
+has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
+{
+ /* 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. */
+ if (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)
+ return true;
+
+ /* Vector Floating-Point Instructions requiring argument frm. */
+ if (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)
+ {
+ /* 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. */
+ if (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
+ == INTEGER_TYPE)
+ return true;
+ }
+ return false;
+}
Is is possible to use instance.base.has_rounding_mode_operand_p ?
So that we won't need to write this long code.
+ return ((0 == strcmp (value->overload_name, key->overload_name))
>>strcmp (value->overload_name, key->overload_name) == 0
juzhe.zhong@rivai.ai
From: Li Xu
Date: 2023-10-30 17:34
To: gcc-patches
CC: kito.cheng; palmer; juzhe.zhong; xuli
Subject: [PATCH V4] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
From: xuli <xuli1@eswincomputing.com>
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.
We validated this framework by the vmv_v intrinsic API(s), and we will
add more intrins API support in the underlying patches.
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.
(has_vxrm_or_frm_p): New function impl.
(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 | 255 +++++++++++++++++-
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, 653 insertions(+), 11 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..e9af77d4f63 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -80,6 +80,31 @@ 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. */
+ 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 +116,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 +2644,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 +3408,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 +3436,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 +3459,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 +3470,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 +3480,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 +4066,147 @@ 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 ();
+}
+
+bool
+has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
+{
+ /* 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. */
+ if (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)
+ return true;
+
+ /* Vector Floating-Point Instructions requiring argument frm. */
+ if (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)
+ {
+ /* 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. */
+ if (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);
+ 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 ((0 == strcmp (value->overload_name, key->overload_name))
+ && 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 +4355,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 +4372,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]);
@@ -4204,8 +4422,27 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
tree fndecl, unsigned int nargs, tree *args)
{
const registered_function &rfn = *(*registered_functions)[code];
- return function_checker (location, rfn.instance, fndecl,
- TREE_TYPE (rfn.decl), nargs, args).check ();
+ return function_checker (location, rfn.instance, fndecl, 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
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
--------------
Li Xu
>Thanks.
>
>I like this 'HASH' solution which is much more reasonable to me.
>
>Some comments here:
>
>+bool
>+has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
>+{
>+ /* 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. */
>+ if (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)
>+ return true;
>+
>+ /* Vector Floating-Point Instructions requiring argument frm. */
>+ if (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)
>+ {
>+ /* 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. */
>+ if (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
>+ == INTEGER_TYPE)
>+ return true;
>+ }
>+ return false;
>+}
>Is is possible to use instance.base.has_rounding_mode_operand_p ?
>So that we won't need to write this long code.
Taking vfadd as an example, because the overloaded function names of vfadd and frm vfadd are the same,
in order to avoid conflicts, the overloaded function is declared as void __riscv_vfadd (void),
so the instance obtained when entering the hook is always vfadd, not frm vfadd,
so I cannot rely on instance to distinguish whether frm is needed.
vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);// instance.base.has_rounding_mode_operand_p is always false
vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned
int frm, size_t vl);
>
>+ return ((0 == strcmp (value->overload_name, key->overload_name))
>>>strcmp (value->overload_name, key->overload_name) == 0
>
>
>
>
>juzhe.zhong@rivai.ai
>
>From: Li Xu
>Date: 2023-10-30 17:34
>To: gcc-patches
>CC: kito.cheng; palmer; juzhe.zhong; xuli
>Subject: [PATCH V4] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
>From: xuli <xuli1@eswincomputing.com>
>
>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.
>
>We validated this framework by the vmv_v intrinsic API(s), and we will
>add more intrins API support in the underlying patches.
>
>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.
> (has_vxrm_or_frm_p): New function impl.
> (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 | 255 +++++++++++++++++-
>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, 653 insertions(+), 11 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..e9af77d4f63 100644
>--- a/gcc/config/riscv/riscv-vector-builtins.cc
>+++ b/gcc/config/riscv/riscv-vector-builtins.cc
>@@ -80,6 +80,31 @@ 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. */
>+ 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 +116,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 +2644,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 +3408,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 +3436,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 +3459,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 +3470,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 +3480,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 +4066,147 @@ 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 ();
>+}
>+
>+bool
>+has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
>+{
>+ /* 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. */
>+ if (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)
>+ return true;
>+
>+ /* Vector Floating-Point Instructions requiring argument frm. */
>+ if (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)
>+ {
>+ /* 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. */
>+ if (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);
>+ 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 ((0 == strcmp (value->overload_name, key->overload_name))
>+ && 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 +4355,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 +4372,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]);
>@@ -4204,8 +4422,27 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
> tree fndecl, unsigned int nargs, tree *args)
>{
> const registered_function &rfn = *(*registered_functions)[code];
>- return function_checker (location, rfn.instance, fndecl,
>- TREE_TYPE (rfn.decl), nargs, args).check ();
>+ return function_checker (location, rfn.instance, fndecl, 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
>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
>
>
Ok. Understand.
Could you add wrapper "maybe_require_vxrm_p" and "maybe_require_frm_p" ?
static bool
maybe_require_frm_p
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
juzhe.zhong@rivai.ai
From: Li Xu
Date: 2023-10-30 18:04
To: juzhe.zhong; gcc-patches
CC: kito.cheng; palmer
Subject: Re: Re: [PATCH V4] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
--------------
Li Xu
>Thanks.
>
>I like this 'HASH' solution which is much more reasonable to me.
>
>Some comments here:
>
>+bool
>+has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
>+{
>+ /* 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. */
>+ if (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)
>+ return true;
>+
>+ /* Vector Floating-Point Instructions requiring argument frm. */
>+ if (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)
>+ {
>+ /* 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. */
>+ if (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
>+ == INTEGER_TYPE)
>+ return true;
>+ }
>+ return false;
>+}
>Is is possible to use instance.base.has_rounding_mode_operand_p ?
>So that we won't need to write this long code.
Taking vfadd as an example, because the overloaded function names of vfadd and frm vfadd are the same,
in order to avoid conflicts, the overloaded function is declared as void __riscv_vfadd (void),
so the instance obtained when entering the hook is always vfadd, not frm vfadd,
so I cannot rely on instance to distinguish whether frm is needed.
vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);// instance.base.has_rounding_mode_operand_p is always false
vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned
int frm, size_t vl);
>
>+ return ((0 == strcmp (value->overload_name, key->overload_name))
>>>strcmp (value->overload_name, key->overload_name) == 0
>
>
>
>
>juzhe.zhong@rivai.ai
>
>From: Li Xu
>Date: 2023-10-30 17:34
>To: gcc-patches
>CC: kito.cheng; palmer; juzhe.zhong; xuli
>Subject: [PATCH V4] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
>From: xuli <xuli1@eswincomputing.com>
>
>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.
>
>We validated this framework by the vmv_v intrinsic API(s), and we will
>add more intrins API support in the underlying patches.
>
>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.
> (has_vxrm_or_frm_p): New function impl.
> (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 | 255 +++++++++++++++++-
>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, 653 insertions(+), 11 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..e9af77d4f63 100644
>--- a/gcc/config/riscv/riscv-vector-builtins.cc
>+++ b/gcc/config/riscv/riscv-vector-builtins.cc
>@@ -80,6 +80,31 @@ 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. */
>+ 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 +116,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 +2644,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 +3408,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 +3436,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 +3459,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 +3470,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 +3480,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 +4066,147 @@ 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 ();
>+}
>+
>+bool
>+has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
>+{
>+ /* 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. */
>+ if (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)
>+ return true;
>+
>+ /* Vector Floating-Point Instructions requiring argument frm. */
>+ if (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)
>+ {
>+ /* 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. */
>+ if (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);
>+ 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 ((0 == strcmp (value->overload_name, key->overload_name))
>+ && 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 +4355,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 +4372,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]);
>@@ -4204,8 +4422,27 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
> tree fndecl, unsigned int nargs, tree *args)
>{
> const registered_function &rfn = *(*registered_functions)[code];
>- return function_checker (location, rfn.instance, fndecl,
>- TREE_TYPE (rfn.decl), nargs, args).check ();
>+ return function_checker (location, rfn.instance, fndecl, 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
>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
>
>
OK, I will send patch v5.
--------------
Li Xu
>Ok. Understand.
>
>Could you add wrapper "maybe_require_vxrm_p" and "maybe_require_frm_p" ?
>
>static bool
>maybe_require_frm_p
>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
>
>
>
>juzhe.zhong@rivai.ai
>
>From: Li Xu
>Date: 2023-10-30 18:04
>To: juzhe.zhong; gcc-patches
>CC: kito.cheng; palmer
>Subject: Re: Re: [PATCH V4] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
>
>
>
>--------------
>
>
>
>Li Xu
>
>
>
>>Thanks.
>
>
>
>>
>
>
>
>>I like this 'HASH' solution which is much more reasonable to me.
>
>
>
>>
>
>
>
>>Some comments here:
>
>
>
>>
>
>
>
>>+bool
>
>
>
>>+has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
>
>
>
>>+{
>
>
>
>>+ /* 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. */
>
>
>
>>+ if (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)
>
>
>
>>+ return true;
>
>
>
>>+
>
>
>
>>+ /* Vector Floating-Point Instructions requiring argument frm. */
>
>
>
>>+ if (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)
>
>
>
>>+ {
>
>
>
>>+ /* 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. */
>
>
>
>>+ if (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
>
>
>
>>+ == INTEGER_TYPE)
>
>
>
>>+ return true;
>
>
>
>>+ }
>
>
>
>>+ return false;
>
>
>
>>+}
>
>
>
>>Is is possible to use instance.base.has_rounding_mode_operand_p ?
>
>
>
>>So that we won't need to write this long code.
>
>
>Taking vfadd as an example, because the overloaded function names of vfadd and frm vfadd are the same,
>in order to avoid conflicts, the overloaded function is declared as void __riscv_vfadd (void),
>so the instance obtained when entering the hook is always vfadd, not frm vfadd,
>so I cannot rely on instance to distinguish whether frm is needed.
>
>vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);// instance.base.has_rounding_mode_operand_p is always false
>
>vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned
>
> int frm, size_t vl);
>
>
>
>
>>
>
>
>
>>+ return ((0 == strcmp (value->overload_name, key->overload_name))
>
>
>
>>>>strcmp (value->overload_name, key->overload_name) == 0
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>juzhe.zhong@rivai.ai
>
>
>
>>
>
>
>
>>From: Li Xu
>
>
>
>>Date: 2023-10-30 17:34
>
>
>
>>To: gcc-patches
>
>
>
>>CC: kito.cheng; palmer; juzhe.zhong; xuli
>
>
>
>>Subject: [PATCH V4] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
>
>
>
>>From: xuli <xuli1@eswincomputing.com>
>
>
>
>>
>
>
>
>>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.
>
>
>
>>
>
>
>
>>We validated this framework by the vmv_v intrinsic API(s), and we will
>
>
>
>>add more intrins API support in the underlying patches.
>
>
>
>>
>
>
>
>>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.
>
>
>
>> (has_vxrm_or_frm_p): New function impl.
>
>
>
>> (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 | 255 +++++++++++++++++-
>
>
>
>>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, 653 insertions(+), 11 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..e9af77d4f63 100644
>
>
>
>>--- a/gcc/config/riscv/riscv-vector-builtins.cc
>
>
>
>>+++ b/gcc/config/riscv/riscv-vector-builtins.cc
>
>
>
>>@@ -80,6 +80,31 @@ 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. */
>
>
>
>>+ 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 +116,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 +2644,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 +3408,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 +3436,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 +3459,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 +3470,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 +3480,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 +4066,147 @@ 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 ();
>
>
>
>>+}
>
>
>
>>+
>
>
>
>>+bool
>
>
>
>>+has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
>
>
>
>>+{
>
>
>
>>+ /* 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. */
>
>
>
>>+ if (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)
>
>
>
>>+ return true;
>
>
>
>>+
>
>
>
>>+ /* Vector Floating-Point Instructions requiring argument frm. */
>
>
>
>>+ if (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)
>
>
>
>>+ {
>
>
>
>>+ /* 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. */
>
>
>
>>+ if (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);
>
>
>
>>+ 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 ((0 == strcmp (value->overload_name, key->overload_name))
>
>
>
>>+ && 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 +4355,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 +4372,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]);
>
>
>
>>@@ -4204,8 +4422,27 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
>
>
>
>> tree fndecl, unsigned int nargs, tree *args)
>
>
>
>>{
>
>
>
>> const registered_function &rfn = *(*registered_functions)[code];
>
>
>
>>- return function_checker (location, rfn.instance, fndecl,
>
>
>
>>- TREE_TYPE (rfn.decl), nargs, args).check ();
>
>
>
>>+ return function_checker (location, rfn.instance, fndecl, 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
>
>
>
>>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
>
>
>
>>
>
>
>
>>
>
>
Thanks li for making this happen, overall LGTM excepts some nit comments as below.
> We validated this framework by the vmv_v intrinsic API(s), and we will
> add more intrins API support in the underlying patches.
Please help to remove above part from commit log as out of date.
> - orig_fndecl, nargs, args);
> + fndecl, nargs, args);
Is above change necessary?
> + /* 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. */
The hash doesn't require base and shape anymore ? If so I bet the comments need minor updates.
> - return function_checker (location, rfn.instance, fndecl,
> - TREE_TYPE (rfn.decl), nargs, args).check ();
> + return function_checker (location, rfn.instance, fndecl, TREE_TYPE (rfn.decl),
> + nargs, args)
> + .check ();
Only format changes?
> + else if (has_vxrm_or_frm_p (instance, arglist) && (i == (len - 2)))
> + argument_types.safe_push (unsigned_type_node);
How about move the comments from the head of has_vxrm_or_frm_p to here? Given the has_vxrm_or_frm_p
looks like simple predicate function return true or false, which may be irrelevant to the hash part.
Pan
-----Original Message-----
From: Li Xu <xuli1@eswincomputing.com>
Sent: Monday, October 30, 2023 6:17 PM
To: juzhe.zhong <juzhe.zhong@rivai.ai>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: kito.cheng <kito.cheng@gmail.com>; palmer <palmer@dabbelt.com>
Subject: Re: Re: [PATCH V4] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
OK, I will send patch v5.
--------------
Li Xu
>Ok. Understand.
>
>Could you add wrapper "maybe_require_vxrm_p" and "maybe_require_frm_p" ?
>
>static bool
>maybe_require_frm_p
>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
>
>
>
>juzhe.zhong@rivai.ai
>
>From: Li Xu
>Date: 2023-10-30 18:04
>To: juzhe.zhong; gcc-patches
>CC: kito.cheng; palmer
>Subject: Re: Re: [PATCH V4] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
>
>
>
>--------------
>
>
>
>Li Xu
>
>
>
>>Thanks.
>
>
>
>>
>
>
>
>>I like this 'HASH' solution which is much more reasonable to me.
>
>
>
>>
>
>
>
>>Some comments here:
>
>
>
>>
>
>
>
>>+bool
>
>
>
>>+has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
>
>
>
>>+{
>
>
>
>>+ /* 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. */
>
>
>
>>+ if (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)
>
>
>
>>+ return true;
>
>
>
>>+
>
>
>
>>+ /* Vector Floating-Point Instructions requiring argument frm. */
>
>
>
>>+ if (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)
>
>
>
>>+ {
>
>
>
>>+ /* 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. */
>
>
>
>>+ if (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
>
>
>
>>+ == INTEGER_TYPE)
>
>
>
>>+ return true;
>
>
>
>>+ }
>
>
>
>>+ return false;
>
>
>
>>+}
>
>
>
>>Is is possible to use instance.base.has_rounding_mode_operand_p ?
>
>
>
>>So that we won't need to write this long code.
>
>
>Taking vfadd as an example, because the overloaded function names of vfadd and frm vfadd are the same,
>in order to avoid conflicts, the overloaded function is declared as void __riscv_vfadd (void),
>so the instance obtained when entering the hook is always vfadd, not frm vfadd,
>so I cannot rely on instance to distinguish whether frm is needed.
>
>vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);// instance.base.has_rounding_mode_operand_p is always false
>
>vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned
>
> int frm, size_t vl);
>
>
>
>
>>
>
>
>
>>+ return ((0 == strcmp (value->overload_name, key->overload_name))
>
>
>
>>>>strcmp (value->overload_name, key->overload_name) == 0
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>juzhe.zhong@rivai.ai
>
>
>
>>
>
>
>
>>From: Li Xu
>
>
>
>>Date: 2023-10-30 17:34
>
>
>
>>To: gcc-patches
>
>
>
>>CC: kito.cheng; palmer; juzhe.zhong; xuli
>
>
>
>>Subject: [PATCH V4] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
>
>
>
>>From: xuli <xuli1@eswincomputing.com>
>
>
>
>>
>
>
>
>>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.
>
>
>
>>
>
>
>
>>We validated this framework by the vmv_v intrinsic API(s), and we will
>
>
>
>>add more intrins API support in the underlying patches.
>
>
>
>>
>
>
>
>>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.
>
>
>
>> (has_vxrm_or_frm_p): New function impl.
>
>
>
>> (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 | 255 +++++++++++++++++-
>
>
>
>>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, 653 insertions(+), 11 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..e9af77d4f63 100644
>
>
>
>>--- a/gcc/config/riscv/riscv-vector-builtins.cc
>
>
>
>>+++ b/gcc/config/riscv/riscv-vector-builtins.cc
>
>
>
>>@@ -80,6 +80,31 @@ 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. */
>
>
>
>>+ 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 +116,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 +2644,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 +3408,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 +3436,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 +3459,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 +3470,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 +3480,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 +4066,147 @@ 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 ();
>
>
>
>>+}
>
>
>
>>+
>
>
>
>>+bool
>
>
>
>>+has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
>
>
>
>>+{
>
>
>
>>+ /* 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. */
>
>
>
>>+ if (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)
>
>
>
>>+ return true;
>
>
>
>>+
>
>
>
>>+ /* Vector Floating-Point Instructions requiring argument frm. */
>
>
>
>>+ if (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)
>
>
>
>>+ {
>
>
>
>>+ /* 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. */
>
>
>
>>+ if (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);
>
>
>
>>+ 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 ((0 == strcmp (value->overload_name, key->overload_name))
>
>
>
>>+ && 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 +4355,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 +4372,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]);
>
>
>
>>@@ -4204,8 +4422,27 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
>
>
>
>> tree fndecl, unsigned int nargs, tree *args)
>
>
>
>>{
>
>
>
>> const registered_function &rfn = *(*registered_functions)[code];
>
>
>
>>- return function_checker (location, rfn.instance, fndecl,
>
>
>
>>- TREE_TYPE (rfn.decl), nargs, args).check ();
>
>
>
>>+ return function_checker (location, rfn.instance, fndecl, 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
>
>
>
>>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
>
>
>
>>
>
>
>
>>
>
>
>> We validated this framework by the vmv_v intrinsic API(s), and we will
>> add more intrins API support in the underlying patches.
>
>Is above change necessary?
The modification here is because the check function of vset/vget crashes.
for example:
__riscv_vget_i8m1(src, 0);
The "orig_fndecl" obtained by entering the hook is:
void __riscv_vget_i8m1(void);
The "fndecl" found with hash value is:
vint8m1_t __riscv_vget_v_i8m2_i8m1(vint8m2_t src, size_t index);
struct vget_def : public misc_def
{
bool check (function_checker &c) const override
{
poly_int64 outer_size = GET_MODE_SIZE (c.arg_mode (0));//if use "orig_fndecl", c.arg_mode = null, will crash.
poly_int64 inner_size = GET_MODE_SIZE (c.ret_mode ());
unsigned int nvecs = exact_div (outer_size, inner_size).to_constant ();
return c.require_immediate (1, 0, nvecs - 1);
}
};
>> - return function_checker (location, rfn.instance, fndecl,
>> - TREE_TYPE (rfn.decl), nargs, args).check ();
>> + return function_checker (location, rfn.instance, fndecl, TREE_TYPE (rfn.decl),
>> + nargs, args)
>> + .check ();
>
>Only format changes?
I changed the format by mistake, it will be corrected in the next patch.
--------------
Li Xu
>Thanks li for making this happen, overall LGTM excepts some nit comments as below.
>
>> We validated this framework by the vmv_v intrinsic API(s), and we will
>> add more intrins API support in the underlying patches.
>
>Please help to remove above part from commit log as out of date.
>
>> - orig_fndecl, nargs, args);
>> + fndecl, nargs, args);
>
>Is above change necessary?
>
>> + /* 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. */
>
>The hash doesn't require base and shape anymore ? If so I bet the comments need minor updates.
>
>> - return function_checker (location, rfn.instance, fndecl,
>> - TREE_TYPE (rfn.decl), nargs, args).check ();
>> + return function_checker (location, rfn.instance, fndecl, TREE_TYPE (rfn.decl),
>> + nargs, args)
>> + .check ();
>
>Only format changes?
>
>> + else if (has_vxrm_or_frm_p (instance, arglist) && (i == (len - 2)))
>> + argument_types.safe_push (unsigned_type_node);
>
>How about move the comments from the head of has_vxrm_or_frm_p to here? Given the has_vxrm_or_frm_p
>looks like simple predicate function return true or false, which may be irrelevant to the hash part.
>
>Pan
>
>-----Original Message-----
>From: Li Xu <xuli1@eswincomputing.com>
>Sent: Monday, October 30, 2023 6:17 PM
>To: juzhe.zhong <juzhe.zhong@rivai.ai>; gcc-patches <gcc-patches@gcc.gnu.org>
>Cc: kito.cheng <kito.cheng@gmail.com>; palmer <palmer@dabbelt.com>
>Subject: Re: Re: [PATCH V4] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
>
>
>OK, I will send patch v5.
>
>
>--------------
>
>
>
>Li Xu
>
>
>
>>Ok. Understand.
>
>
>
>>
>
>
>
>>Could you add wrapper "maybe_require_vxrm_p" and "maybe_require_frm_p" ?
>
>
>
>>
>
>
>
>>static bool
>
>
>
>>maybe_require_frm_p
>
>
>
>>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
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>juzhe.zhong@rivai.ai
>
>
>
>>
>
>
>
>>From: Li Xu
>
>
>
>>Date: 2023-10-30 18:04
>
>
>
>>To: juzhe.zhong; gcc-patches
>
>
>
>>CC: kito.cheng; palmer
>
>
>
>>Subject: Re: Re: [PATCH V4] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>--------------
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>Li Xu
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>Thanks.
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>I like this 'HASH' solution which is much more reasonable to me.
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>Some comments here:
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+bool
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+{
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ /* 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. */
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ if (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)
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ return true;
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ /* Vector Floating-Point Instructions requiring argument frm. */
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ if (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)
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ {
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ /* 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. */
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ if (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ == INTEGER_TYPE)
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ return true;
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ }
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ return false;
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+}
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>Is is possible to use instance.base.has_rounding_mode_operand_p ?
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>So that we won't need to write this long code.
>
>
>
>>
>
>
>
>>
>
>
>
>>Taking vfadd as an example, because the overloaded function names of vfadd and frm vfadd are the same,
>
>
>
>>in order to avoid conflicts, the overloaded function is declared as void __riscv_vfadd (void),
>
>
>
>>so the instance obtained when entering the hook is always vfadd, not frm vfadd,
>
>
>
>>so I cannot rely on instance to distinguish whether frm is needed.
>
>
>
>>
>
>
>
>>vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);// instance.base.has_rounding_mode_operand_p is always false
>
>
>
>>
>
>
>
>>vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned
>
>
>
>>
>
>
>
>> int frm, size_t vl);
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ return ((0 == strcmp (value->overload_name, key->overload_name))
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>>>strcmp (value->overload_name, key->overload_name) == 0
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>juzhe.zhong@rivai.ai
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>From: Li Xu
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>Date: 2023-10-30 17:34
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>To: gcc-patches
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>CC: kito.cheng; palmer; juzhe.zhong; xuli
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>Subject: [PATCH V4] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>From: xuli <xuli1@eswincomputing.com>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>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.
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>We validated this framework by the vmv_v intrinsic API(s), and we will
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>add more intrins API support in the underlying patches.
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>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.
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>> (has_vxrm_or_frm_p): New function impl.
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>> (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 | 255 +++++++++++++++++-
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>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, 653 insertions(+), 11 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..e9af77d4f63 100644
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>--- a/gcc/config/riscv/riscv-vector-builtins.cc
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+++ b/gcc/config/riscv/riscv-vector-builtins.cc
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>@@ -80,6 +80,31 @@ 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. */
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ 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 +116,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 +2644,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 +3408,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 +3436,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 +3459,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 +3470,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 +3480,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 +4066,147 @@ 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 ();
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+}
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+bool
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+{
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ /* 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. */
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ if (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)
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ return true;
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ /* Vector Floating-Point Instructions requiring argument frm. */
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ if (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)
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ {
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ /* 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. */
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ if (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);
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ 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 ((0 == strcmp (value->overload_name, key->overload_name))
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ && 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 +4355,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 +4372,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]);
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>@@ -4204,8 +4422,27 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>> tree fndecl, unsigned int nargs, tree *args)
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>{
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>> const registered_function &rfn = *(*registered_functions)[code];
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>- return function_checker (location, rfn.instance, fndecl,
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>- TREE_TYPE (rfn.decl), nargs, args).check ();
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>+ return function_checker (location, rfn.instance, fndecl, 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
>
>
>
>>
>
>
>
>>
>
>
>
>>
>
>
>
>>>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,31 @@ 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. */
+ 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 +116,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 +2644,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 +3408,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 +3436,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 +3459,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 +3470,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 +3480,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 +4066,147 @@ 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 ();
+}
+
+bool
+has_vxrm_or_frm_p (function_instance &instance, const vec<tree, va_gc> &arglist)
+{
+ /* 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. */
+ if (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)
+ return true;
+
+ /* Vector Floating-Point Instructions requiring argument frm. */
+ if (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)
+ {
+ /* 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. */
+ if (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);
+ 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 ((0 == strcmp (value->overload_name, key->overload_name))
+ && 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 +4355,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 +4372,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]);
@@ -4204,8 +4422,27 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
tree fndecl, unsigned int nargs, tree *args)
{
const registered_function &rfn = *(*registered_functions)[code];
- return function_checker (location, rfn.instance, fndecl,
- TREE_TYPE (rfn.decl), nargs, args).check ();
+ return function_checker (location, rfn.instance, fndecl, 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
@@ -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);
+}