public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
@ 2023-10-31  9:03 Li Xu
  2023-10-31  9:07 ` juzhe.zhong
  0 siblings, 1 reply; 7+ messages in thread
From: Li Xu @ 2023-10-31  9:03 UTC (permalink / raw)
  To: gcc-patches; +Cc: kito.cheng, palmer, juzhe.zhong, xuli

From: xuli <xuli1@eswincomputing.com>

Update in v6:
* Rename maybe_require_frm_p to may_require_frm_p.
* Rename maybe_require_vxrm_p to may_require_vxrm_p.
* Move may_require_frm_p and may_require_vxrm_p to function_base.

Update in v5:
* Split has_vxrm_or_frm_p into maybe_require_frm_p and
  maybe_require_vxrm_p.
* Adjust comments.

Update in v4:
* Remove class function_resolver.
* Remove function get_non_overloaded_instance.
* Add overloaded hash traits for non-overloaded intrinsic.
* All overloaded intrinsics are implemented, and the tests pass.

Update in v3:

* Rewrite comment for overloaded function add.
* Move get_non_overloaded_instance to function_base.

Update in v2:

* Add get_non_overloaded_instance for function instance.
* Fix overload check for policy function.
* Enrich the test cases check.

Original log:

This patch would like add the framework to support the RVV overloaded
intrinsic API in riscv-xxx-xxx-gcc, like riscv-xxx-xxx-g++ did.

However, it almost leverage the hook TARGET_RESOLVE_OVERLOADED_BUILTIN
with below steps.

* Register overloaded functions.
* Add function_resolver for overloaded function resolving.
* Add resolve API for function shape with default implementation.
* Implement HOOK for navigating the overloaded API to non-overloaded API.

gcc/ChangeLog:

        * config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): New function for the hook.
        (riscv_register_pragmas): Register the hook.
        * config/riscv/riscv-protos.h (resolve_overloaded_builtin): New decl.
        * config/riscv/riscv-vector-builtins-bases.cc: New function impl.
        * 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 (function_base::may_require_frm_p): Ditto.
        (function_base::may_require_vxrm_p): Ditto.

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-bases.cc      |  69 +++++-
 .../riscv/riscv-vector-builtins-shapes.cc     |   1 +
 gcc/config/riscv/riscv-vector-builtins.cc     | 226 +++++++++++++++++-
 gcc/config/riscv/riscv-vector-builtins.h      |  27 ++-
 .../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 +++
 24 files changed, 708 insertions(+), 18 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 = &empty;
+
+  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-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index 0b1409a52e0..9bc2be2a6da 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -262,7 +262,8 @@ public:
    vremu/vsadd/vsaddu/vssub/vssubu
    vfadd/vfsub/
 */
-template<rtx_code CODE, enum frm_op_type FRM_OP = NO_FRM>
+template <rtx_code CODE, bool MAY_REQUIRE_FRM = false,
+	  enum frm_op_type FRM_OP = NO_FRM>
 class binop : public function_base
 {
 public:
@@ -271,6 +272,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return MAY_REQUIRE_FRM; }
+
   rtx expand (function_expander &e) const override
   {
     switch (e.op_info->op)
@@ -308,6 +311,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
@@ -397,6 +402,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     switch (e.op_info->op)
@@ -630,6 +637,8 @@ class sat_op : public function_base
 public:
   bool has_rounding_mode_operand_p () const override { return true; }
 
+  bool may_require_vxrm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     switch (e.op_info->op)
@@ -652,6 +661,8 @@ class vnclip : public function_base
 public:
   bool has_rounding_mode_operand_p () const override { return true; }
 
+  bool may_require_vxrm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     switch (e.op_info->op)
@@ -1024,6 +1035,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     return e.use_exact_insn (
@@ -1040,6 +1053,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
 
   rtx expand (function_expander &e) const override
@@ -1064,6 +1079,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
 
   rtx expand (function_expander &e) const override
@@ -1087,6 +1104,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
 
   rtx expand (function_expander &e) const override
@@ -1111,6 +1130,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
 
   rtx expand (function_expander &e) const override
@@ -1134,6 +1155,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
 
   rtx expand (function_expander &e) const override
@@ -1157,6 +1180,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
 
   rtx expand (function_expander &e) const override
@@ -1181,6 +1206,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
 
   rtx expand (function_expander &e) const override
@@ -1204,6 +1231,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
 
   rtx expand (function_expander &e) const override
@@ -1228,6 +1257,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
 
   rtx expand (function_expander &e) const override
@@ -1251,6 +1282,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
 
   rtx expand (function_expander &e) const override
@@ -1274,6 +1307,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
 
   rtx expand (function_expander &e) const override
@@ -1297,6 +1332,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
 
   rtx expand (function_expander &e) const override
@@ -1321,6 +1358,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     if (e.op_info->op == OP_TYPE_vf)
@@ -1392,6 +1431,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     return e.use_exact_insn (code_for_pred_fcvt_x_f (UNSPEC, e.arg_mode (0)));
@@ -1418,6 +1459,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     if (e.op_info->op == OP_TYPE_x_v)
@@ -1439,6 +1482,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     return e.use_exact_insn (
@@ -1483,6 +1528,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     return e.use_exact_insn (
@@ -1510,6 +1557,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     if (e.op_info->op == OP_TYPE_f_w)
@@ -1555,6 +1604,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
 
+  bool may_require_frm_p () const override { return true; }
+
   bool apply_mask_policy_p () const override { return false; }
 
   rtx expand (function_expander &e) const override
@@ -2164,20 +2215,20 @@ static CONSTEXPR const mask_misc<UNSPEC_VMSIF> vmsif_obj;
 static CONSTEXPR const mask_misc<UNSPEC_VMSOF> vmsof_obj;
 static CONSTEXPR const viota viota_obj;
 static CONSTEXPR const vid vid_obj;
-static CONSTEXPR const binop<PLUS> vfadd_obj;
-static CONSTEXPR const binop<MINUS> vfsub_obj;
-static CONSTEXPR const binop<PLUS, HAS_FRM> vfadd_frm_obj;
-static CONSTEXPR const binop<MINUS, HAS_FRM> vfsub_frm_obj;
+static CONSTEXPR const binop<PLUS, true> vfadd_obj;
+static CONSTEXPR const binop<MINUS, true> vfsub_obj;
+static CONSTEXPR const binop<PLUS, true, HAS_FRM> vfadd_frm_obj;
+static CONSTEXPR const binop<MINUS, true, HAS_FRM> vfsub_frm_obj;
 static CONSTEXPR const reverse_binop<MINUS> vfrsub_obj;
 static CONSTEXPR const reverse_binop<MINUS, HAS_FRM> vfrsub_frm_obj;
 static CONSTEXPR const widen_binop_fp<PLUS> vfwadd_obj;
 static CONSTEXPR const widen_binop_fp<PLUS, HAS_FRM> vfwadd_frm_obj;
 static CONSTEXPR const widen_binop_fp<MINUS> vfwsub_obj;
 static CONSTEXPR const widen_binop_fp<MINUS, HAS_FRM> vfwsub_frm_obj;
-static CONSTEXPR const binop<MULT> vfmul_obj;
-static CONSTEXPR const binop<MULT, HAS_FRM> vfmul_frm_obj;
-static CONSTEXPR const binop<DIV> vfdiv_obj;
-static CONSTEXPR const binop<DIV, HAS_FRM> vfdiv_frm_obj;
+static CONSTEXPR const binop<MULT, true> vfmul_obj;
+static CONSTEXPR const binop<MULT,  true, HAS_FRM> vfmul_frm_obj;
+static CONSTEXPR const binop<DIV, true> vfdiv_obj;
+static CONSTEXPR const binop<DIV,  true, HAS_FRM> vfdiv_frm_obj;
 static CONSTEXPR const reverse_binop<DIV> vfrdiv_obj;
 static CONSTEXPR const reverse_binop<DIV, HAS_FRM> vfrdiv_frm_obj;
 static CONSTEXPR const widen_binop_fp<MULT> vfwmul_obj;
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..e7564b9cf7c 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -80,6 +80,32 @@ public:
 
   /* The decl itself.  */
   tree GTY ((skip)) decl;
+
+  /* The overload hash of non-overloaded intrinsic is determined by
+     the overload name and argument list. Adding the overload name to
+     the hash is also to address the following situations:
+     vint16mf4_t  __riscv_vreinterpret_i16mf4 (vfloat16mf4_t src);
+     vuint16mf4_t __riscv_vreinterpret_u16mf4 (vfloat16mf4_t src);
+     The base, shape and argument list of the vreinterpret instance are
+     the same, only the overload name is different. Therefore, it is
+     enough to add overload_name and argument list to the hash value.*/
+  const char *overload_name;
+
+  /* The argument list part of the hash value. Add the unsigned/signed type
+     and machine mode of each argument to the hash value. */
+  vec<tree> GTY ((skip)) argument_types;
+
+  /* True if the decl represents an overloaded function that needs to be
+     resolved. */
+  bool overloaded_p;
+
+  /* The hash value to indicate the non-overloaded function. Generate hash value
+     based on overload_name and argument_types. */
+  hashval_t overloaded_hash () const;
+
+  /* Generate hash value based on the overload_name and the argument list passed
+     by the user when calling. */
+  hashval_t overloaded_hash (const vec<tree, va_gc> &);
 };
 
 /* Hash traits for registered_function.  */
@@ -91,6 +117,14 @@ struct registered_function_hasher : nofree_ptr_hash<registered_function>
   static bool equal (value_type, const compare_type &);
 };
 
+/* Hash traits for overload registered_function. */
+struct non_overloaded_registered_function_hasher
+  : nofree_ptr_hash<registered_function>
+{
+  static hashval_t hash (value_type);
+  static bool equal (value_type, const compare_type &);
+};
+
 /* Static information about each RVV type.  */
 static CONSTEXPR const vector_type_info vector_types[] = {
 #define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, ARGS...)                          \
@@ -2611,6 +2645,12 @@ static GTY (()) vec<registered_function *, va_gc> *registered_functions;
    overloaded functions.  */
 static hash_table<registered_function_hasher> *function_table;
 
+/* All registered function decls, hashed on overload_name and argument list
+   of the registered_function.  This is used for looking up implementations
+   of non-overloaded functions. */
+static hash_table<non_overloaded_registered_function_hasher>
+  *non_overloaded_function_table;
+
 /* RAII class for enabling enough RVV features to define the built-in
    types and implement the riscv_vector.h pragma.
 
@@ -3369,7 +3409,9 @@ function_builder::get_attributes (const function_instance &instance)
 registered_function &
 function_builder::add_function (const function_instance &instance,
 				const char *name, tree fntype, tree attrs,
-				bool placeholder_p)
+				bool placeholder_p, const char *overload_name,
+				const vec<tree> &argument_types,
+				bool overloaded_p = false)
 {
   unsigned int code = vec_safe_length (registered_functions);
   code = (code << RISCV_BUILTIN_SHIFT) + RISCV_BUILTIN_VECTOR;
@@ -3395,6 +3437,9 @@ function_builder::add_function (const function_instance &instance,
   registered_function &rfn = *ggc_alloc<registered_function> ();
   rfn.instance = instance;
   rfn.decl = decl;
+  rfn.overload_name = overload_name ? xstrdup (overload_name) : NULL;
+  rfn.argument_types = argument_types;
+  rfn.overloaded_p = overloaded_p;
   vec_safe_push (registered_functions, &rfn);
 
   return rfn;
@@ -3415,6 +3460,10 @@ function_builder::add_unique_function (const function_instance &instance,
   if (!check_required_extensions (instance))
     return;
 
+  /* Also add the function under its overloaded alias, if we want
+     a separate decl for each instance of an overloaded function.  */
+  char *overload_name = shape->get_name (*this, instance, true);
+
   /* Add the function under its full (unique) name.  */
   char *name = shape->get_name (*this, instance, false);
   tree fntype
@@ -3422,7 +3471,8 @@ function_builder::add_unique_function (const function_instance &instance,
 				 argument_types.address ());
   tree attrs = get_attributes (instance);
   registered_function &rfn
-    = add_function (instance, name, fntype, attrs, false);
+    = add_function (instance, name, fntype, attrs, false, overload_name,
+		    argument_types.copy ());
 
   /* Enter the function into the hash table.  */
   hashval_t hash = instance.hash ();
@@ -3431,19 +3481,45 @@ function_builder::add_unique_function (const function_instance &instance,
   gcc_assert (!*rfn_slot);
   *rfn_slot = &rfn;
 
-  /* Also add the function under its overloaded alias, if we want
-     a separate decl for each instance of an overloaded function.  */
-  char *overload_name = shape->get_name (*this, instance, true);
   if (overload_name)
     {
       /* Attribute lists shouldn't be shared.  */
       tree attrs = get_attributes (instance);
       bool placeholder_p = !m_direct_overloads;
-      add_function (instance, overload_name, fntype, attrs, placeholder_p);
+      add_function (instance, overload_name, fntype, attrs, placeholder_p, NULL,
+		    vNULL);
+
+      /* Enter the function into the non-overloaded hash table.  */
+      hash = rfn.overloaded_hash ();
+      rfn_slot = non_overloaded_function_table->find_slot_with_hash (&rfn, hash,
+								     INSERT);
+      gcc_assert (!*rfn_slot);
+      *rfn_slot = &rfn;
     }
   obstack_free (&m_string_obstack, name);
 }
 
+/* Add overloaded function for gcc. */
+void
+function_builder::add_overloaded_function (const function_instance &instance,
+					   const function_shape *shape)
+{
+  if (!check_required_extensions (instance))
+    return;
+
+  char *name = shape->get_name (*this, instance, true);
+
+  if (name)
+    {
+      /* To avoid API conflicting, take void return type and void argument
+	 for the overloaded function.  */
+      tree fntype = build_function_type (void_type_node, void_list_node);
+      add_function (instance, name, fntype, NULL_TREE, m_direct_overloads, name,
+		    vNULL, true);
+      obstack_free (&m_string_obstack, name);
+    }
+}
+
 function_call_info::function_call_info (location_t location_in,
 					const function_instance &instance_in,
 					tree fndecl_in)
@@ -3991,6 +4067,122 @@ 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)
+{
+  if (instance.base->may_require_vxrm_p ()
+      || (instance.base->may_require_frm_p ()
+	  && (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
+	      == INTEGER_TYPE)))
+    return true;
+  return false;
+}
+
+hashval_t
+registered_function::overloaded_hash (const vec<tree, va_gc> &arglist)
+{
+  argument_types = vNULL;
+  unsigned int len = arglist.length ();
+
+  for (unsigned int i = 0; i < len; i++)
+    {
+      /* vint8m1_t __riscv_vget_i8m1(vint8m2_t src, size_t index);
+	     When the user calls vget intrinsic, the __riscv_vget_i8m1(src, 1)
+       form is used. The compiler recognizes that the parameter index is signed
+       int, which is inconsistent with size_t, so the index is converted to
+       size_t type in order to get correct hash value. vint8m2_t
+       __riscv_vset(vint8m2_t dest, size_t index, vint8m1_t value); The reason
+       is the same as above. */
+      if ((instance.base == bases::vget && (i == (len - 1)))
+	  || (instance.base == bases::vset && (i == (len - 2))))
+	argument_types.safe_push (size_type_node);
+      /* Vector fixed-point arithmetic instructions requiring argument vxrm.
+	     For example: vuint32m4_t __riscv_vaaddu(vuint32m4_t vs2,
+      vuint32m4_t vs1, unsigned int vxrm, size_t vl); The user calls vaaddu
+      intrinsic in the form of __riscv_vaaddu(vs2, vs1, 2, vl). The compiler
+      recognizes that the parameter vxrm is a signed int, which is inconsistent
+      with the parameter unsigned int vxrm declared by intrinsic, so the
+      parameter vxrm is converted to an unsigned int type in order to get
+      correct hash value.
+
+      Vector Floating-Point Instructions requiring argument frm.
+      DEF_RVV_FUNCTION (vfadd, alu, full_preds, f_vvv_ops)
+      DEF_RVV_FUNCTION (vfadd_frm, alu_frm, full_preds, f_vvv_ops)
+      Taking vfadd as an example, theoretically we can add base or shape to the
+      hash value to distinguish whether the frm parameter is required.
+      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);
+      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned int
+      frm, size_t vl);
+
+	    However, the current registration mechanism of overloaded intinsic for gcc
+      limits the intrinsic obtained by entering the hook to always be vfadd, not
+      vfadd_frm. Therefore, the correct hash value cannot be obtained through the
+      parameter list and overload name, base or shape.
+      +--------+---------------------------+-------------------+
+      | index  | name                      | kind              |
+      +--------+---------------------------+-------------------+
+      | 124733 | __riscv_vfadd             | Overloaded        | <- Hook fun code
+      +--------+---------------------------+-------------------+
+      | 124735 |  __riscv_vfadd_vv_f32m1   | Non-overloaded    |
+      +--------+---------------------------+-------------------+
+      | 124737 | __riscv_vfadd             | Placeholder       |
+      +--------+---------------------------+-------------------+
+      | ...                                                    |
+      +--------+---------------------------+-------------------+
+      | ...                                                    |
+      +--------+---------------------------+-------------------+
+      | 125739 | __riscv_vfadd             | Overloaded        |
+      +--------+---------------------------+-------------------+
+      | 125741 | __riscv_vfadd_vv_f32m1_rm | Non-overloaded    |
+      +--------+---------------------------+-------------------+
+      | 125743 | __riscv_vfadd             | Placeholder       |
+      +--------+---------------------------+-------------------+
+
+	    Therefore, the hash value cannot be added with base or shape, and needs
+      to be distinguished by whether the penultimate parameter is INTEGER_TYPE. */
+      else if (has_vxrm_or_frm_p (instance, arglist) && (i == (len - 2)))
+	argument_types.safe_push (unsigned_type_node);
+      else
+	argument_types.safe_push (TREE_TYPE (arglist[i]));
+    }
+  return overloaded_hash ();
+}
+
+inline hashval_t
+non_overloaded_registered_function_hasher::hash (value_type value)
+{
+  return value->overloaded_hash ();
+}
+
+inline bool
+non_overloaded_registered_function_hasher::equal (value_type value,
+						  const compare_type &key)
+{
+  return ((strcmp (value->overload_name, key->overload_name) == 0)
+	  && value->overloaded_hash () == key->overloaded_hash ());
+}
+
 /* If TYPE is a built-in type defined by the RVV ABI, return the mangled name,
    otherwise return NULL.  */
 const char *
@@ -4139,7 +4331,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 +4348,8 @@ handle_pragma_vector ()
 
   /* Define the functions.  */
   function_table = new hash_table<registered_function_hasher> (1023);
+  non_overloaded_function_table
+    = new hash_table<non_overloaded_registered_function_hasher> (1023);
   function_builder builder;
   for (unsigned int i = 0; i < ARRAY_SIZE (function_groups); ++i)
     builder.register_function_group (function_groups[i]);
@@ -4208,6 +4402,24 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
 			   TREE_TYPE (rfn.decl), nargs, args).check ();
 }
 
+tree
+resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
+{
+  if (code >= vec_safe_length (registered_functions))
+    return NULL_TREE;
+
+  registered_function *rfun = (*registered_functions)[code];
+
+  if (!rfun || !rfun->overloaded_p)
+    return NULL_TREE;
+
+  hashval_t hash = rfun->overloaded_hash (*arglist);
+  registered_function *rfn
+    = non_overloaded_function_table->find_with_hash (rfun, hash);
+  gcc_assert (rfn);
+  return rfn->decl;
+}
+
 function_instance
 get_read_vl_instance (void)
 {
diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
index e358a8e4d91..cd8ccab1724 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.  */
@@ -417,6 +420,12 @@ public:
   /* Return true if intrinsics has rounding mode operand.  */
   virtual bool has_rounding_mode_operand_p () const;
 
+  /* Return true if intrinsics maybe require vxrm operand.  */
+  virtual bool may_require_vxrm_p () const;
+
+  /* Return true if intrinsics maybe require frm operand.  */
+  virtual bool may_require_frm_p () const;
+
   /* Try to fold the given gimple call.  Return the new gimple statement
      on success, otherwise return null.  */
   virtual gimple *fold (gimple_folder &) const { return NULL; }
@@ -674,6 +683,22 @@ function_base::has_rounding_mode_operand_p () const
   return false;
 }
 
+/* We choose to return false by default since most of the intrinsics does
+   not need frm operand.  */
+inline bool
+function_base::may_require_frm_p () const
+{
+  return false;
+}
+
+/* We choose to return false by default since most of the intrinsics does
+   not need vxrm operand.  */
+inline bool
+function_base::may_require_vxrm_p () const
+{
+  return false;
+}
+
 /* Since most of intrinsics can be overloaded, we set it true by default.  */
 inline bool
 function_base::can_be_overloaded_p (enum predication_type_index) const
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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
  2023-10-31  9:03 [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic Li Xu
@ 2023-10-31  9:07 ` juzhe.zhong
  2023-10-31 11:36   ` Li Xu
  0 siblings, 1 reply; 7+ messages in thread
From: juzhe.zhong @ 2023-10-31  9:07 UTC (permalink / raw)
  To: Li Xu, gcc-patches; +Cc: kito.cheng, palmer, Li Xu

LGTM from my side.

Give kito one more day to review it.

Thanks for support this feature !

juzhe.zhong@rivai.ai
 
From: Li Xu
Date: 2023-10-31 17:03
To: gcc-patches
CC: kito.cheng; palmer; juzhe.zhong; xuli
Subject: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
From: xuli <xuli1@eswincomputing.com>
 
Update in v6:
* Rename maybe_require_frm_p to may_require_frm_p.
* Rename maybe_require_vxrm_p to may_require_vxrm_p.
* Move may_require_frm_p and may_require_vxrm_p to function_base.
 
Update in v5:
* Split has_vxrm_or_frm_p into maybe_require_frm_p and
  maybe_require_vxrm_p.
* Adjust comments.
 
Update in v4:
* Remove class function_resolver.
* Remove function get_non_overloaded_instance.
* Add overloaded hash traits for non-overloaded intrinsic.
* All overloaded intrinsics are implemented, and the tests pass.
 
Update in v3:
 
* Rewrite comment for overloaded function add.
* Move get_non_overloaded_instance to function_base.
 
Update in v2:
 
* Add get_non_overloaded_instance for function instance.
* Fix overload check for policy function.
* Enrich the test cases check.
 
Original log:
 
This patch would like add the framework to support the RVV overloaded
intrinsic API in riscv-xxx-xxx-gcc, like riscv-xxx-xxx-g++ did.
 
However, it almost leverage the hook TARGET_RESOLVE_OVERLOADED_BUILTIN
with below steps.
 
* Register overloaded functions.
* Add function_resolver for overloaded function resolving.
* Add resolve API for function shape with default implementation.
* Implement HOOK for navigating the overloaded API to non-overloaded API.
 
gcc/ChangeLog:
 
        * config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): New function for the hook.
        (riscv_register_pragmas): Register the hook.
        * config/riscv/riscv-protos.h (resolve_overloaded_builtin): New decl.
        * config/riscv/riscv-vector-builtins-bases.cc: New function impl.
        * 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 (function_base::may_require_frm_p): Ditto.
        (function_base::may_require_vxrm_p): Ditto.
 
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-bases.cc      |  69 +++++-
.../riscv/riscv-vector-builtins-shapes.cc     |   1 +
gcc/config/riscv/riscv-vector-builtins.cc     | 226 +++++++++++++++++-
gcc/config/riscv/riscv-vector-builtins.h      |  27 ++-
.../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 +++
24 files changed, 708 insertions(+), 18 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 = &empty;
+
+  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-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index 0b1409a52e0..9bc2be2a6da 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -262,7 +262,8 @@ public:
    vremu/vsadd/vsaddu/vssub/vssubu
    vfadd/vfsub/
*/
-template<rtx_code CODE, enum frm_op_type FRM_OP = NO_FRM>
+template <rtx_code CODE, bool MAY_REQUIRE_FRM = false,
+	  enum frm_op_type FRM_OP = NO_FRM>
class binop : public function_base
{
public:
@@ -271,6 +272,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return MAY_REQUIRE_FRM; }
+
   rtx expand (function_expander &e) const override
   {
     switch (e.op_info->op)
@@ -308,6 +311,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
@@ -397,6 +402,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     switch (e.op_info->op)
@@ -630,6 +637,8 @@ class sat_op : public function_base
public:
   bool has_rounding_mode_operand_p () const override { return true; }
+  bool may_require_vxrm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     switch (e.op_info->op)
@@ -652,6 +661,8 @@ class vnclip : public function_base
public:
   bool has_rounding_mode_operand_p () const override { return true; }
+  bool may_require_vxrm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     switch (e.op_info->op)
@@ -1024,6 +1035,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     return e.use_exact_insn (
@@ -1040,6 +1053,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
   rtx expand (function_expander &e) const override
@@ -1064,6 +1079,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
   rtx expand (function_expander &e) const override
@@ -1087,6 +1104,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
   rtx expand (function_expander &e) const override
@@ -1111,6 +1130,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
   rtx expand (function_expander &e) const override
@@ -1134,6 +1155,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
   rtx expand (function_expander &e) const override
@@ -1157,6 +1180,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
   rtx expand (function_expander &e) const override
@@ -1181,6 +1206,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
   rtx expand (function_expander &e) const override
@@ -1204,6 +1231,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
   rtx expand (function_expander &e) const override
@@ -1228,6 +1257,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
   rtx expand (function_expander &e) const override
@@ -1251,6 +1282,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
   rtx expand (function_expander &e) const override
@@ -1274,6 +1307,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
   rtx expand (function_expander &e) const override
@@ -1297,6 +1332,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   bool has_merge_operand_p () const override { return false; }
   rtx expand (function_expander &e) const override
@@ -1321,6 +1358,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     if (e.op_info->op == OP_TYPE_vf)
@@ -1392,6 +1431,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     return e.use_exact_insn (code_for_pred_fcvt_x_f (UNSPEC, e.arg_mode (0)));
@@ -1418,6 +1459,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     if (e.op_info->op == OP_TYPE_x_v)
@@ -1439,6 +1482,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     return e.use_exact_insn (
@@ -1483,6 +1528,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     return e.use_exact_insn (
@@ -1510,6 +1557,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   rtx expand (function_expander &e) const override
   {
     if (e.op_info->op == OP_TYPE_f_w)
@@ -1555,6 +1604,8 @@ public:
     return FRM_OP == HAS_FRM;
   }
+  bool may_require_frm_p () const override { return true; }
+
   bool apply_mask_policy_p () const override { return false; }
   rtx expand (function_expander &e) const override
@@ -2164,20 +2215,20 @@ static CONSTEXPR const mask_misc<UNSPEC_VMSIF> vmsif_obj;
static CONSTEXPR const mask_misc<UNSPEC_VMSOF> vmsof_obj;
static CONSTEXPR const viota viota_obj;
static CONSTEXPR const vid vid_obj;
-static CONSTEXPR const binop<PLUS> vfadd_obj;
-static CONSTEXPR const binop<MINUS> vfsub_obj;
-static CONSTEXPR const binop<PLUS, HAS_FRM> vfadd_frm_obj;
-static CONSTEXPR const binop<MINUS, HAS_FRM> vfsub_frm_obj;
+static CONSTEXPR const binop<PLUS, true> vfadd_obj;
+static CONSTEXPR const binop<MINUS, true> vfsub_obj;
+static CONSTEXPR const binop<PLUS, true, HAS_FRM> vfadd_frm_obj;
+static CONSTEXPR const binop<MINUS, true, HAS_FRM> vfsub_frm_obj;
static CONSTEXPR const reverse_binop<MINUS> vfrsub_obj;
static CONSTEXPR const reverse_binop<MINUS, HAS_FRM> vfrsub_frm_obj;
static CONSTEXPR const widen_binop_fp<PLUS> vfwadd_obj;
static CONSTEXPR const widen_binop_fp<PLUS, HAS_FRM> vfwadd_frm_obj;
static CONSTEXPR const widen_binop_fp<MINUS> vfwsub_obj;
static CONSTEXPR const widen_binop_fp<MINUS, HAS_FRM> vfwsub_frm_obj;
-static CONSTEXPR const binop<MULT> vfmul_obj;
-static CONSTEXPR const binop<MULT, HAS_FRM> vfmul_frm_obj;
-static CONSTEXPR const binop<DIV> vfdiv_obj;
-static CONSTEXPR const binop<DIV, HAS_FRM> vfdiv_frm_obj;
+static CONSTEXPR const binop<MULT, true> vfmul_obj;
+static CONSTEXPR const binop<MULT,  true, HAS_FRM> vfmul_frm_obj;
+static CONSTEXPR const binop<DIV, true> vfdiv_obj;
+static CONSTEXPR const binop<DIV,  true, HAS_FRM> vfdiv_frm_obj;
static CONSTEXPR const reverse_binop<DIV> vfrdiv_obj;
static CONSTEXPR const reverse_binop<DIV, HAS_FRM> vfrdiv_frm_obj;
static CONSTEXPR const widen_binop_fp<MULT> vfwmul_obj;
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..e7564b9cf7c 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -80,6 +80,32 @@ public:
   /* The decl itself.  */
   tree GTY ((skip)) decl;
+
+  /* The overload hash of non-overloaded intrinsic is determined by
+     the overload name and argument list. Adding the overload name to
+     the hash is also to address the following situations:
+     vint16mf4_t  __riscv_vreinterpret_i16mf4 (vfloat16mf4_t src);
+     vuint16mf4_t __riscv_vreinterpret_u16mf4 (vfloat16mf4_t src);
+     The base, shape and argument list of the vreinterpret instance are
+     the same, only the overload name is different. Therefore, it is
+     enough to add overload_name and argument list to the hash value.*/
+  const char *overload_name;
+
+  /* The argument list part of the hash value. Add the unsigned/signed type
+     and machine mode of each argument to the hash value. */
+  vec<tree> GTY ((skip)) argument_types;
+
+  /* True if the decl represents an overloaded function that needs to be
+     resolved. */
+  bool overloaded_p;
+
+  /* The hash value to indicate the non-overloaded function. Generate hash value
+     based on overload_name and argument_types. */
+  hashval_t overloaded_hash () const;
+
+  /* Generate hash value based on the overload_name and the argument list passed
+     by the user when calling. */
+  hashval_t overloaded_hash (const vec<tree, va_gc> &);
};
/* Hash traits for registered_function.  */
@@ -91,6 +117,14 @@ struct registered_function_hasher : nofree_ptr_hash<registered_function>
   static bool equal (value_type, const compare_type &);
};
+/* Hash traits for overload registered_function. */
+struct non_overloaded_registered_function_hasher
+  : nofree_ptr_hash<registered_function>
+{
+  static hashval_t hash (value_type);
+  static bool equal (value_type, const compare_type &);
+};
+
/* Static information about each RVV type.  */
static CONSTEXPR const vector_type_info vector_types[] = {
#define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, ARGS...)                          \
@@ -2611,6 +2645,12 @@ static GTY (()) vec<registered_function *, va_gc> *registered_functions;
    overloaded functions.  */
static hash_table<registered_function_hasher> *function_table;
+/* All registered function decls, hashed on overload_name and argument list
+   of the registered_function.  This is used for looking up implementations
+   of non-overloaded functions. */
+static hash_table<non_overloaded_registered_function_hasher>
+  *non_overloaded_function_table;
+
/* RAII class for enabling enough RVV features to define the built-in
    types and implement the riscv_vector.h pragma.
@@ -3369,7 +3409,9 @@ function_builder::get_attributes (const function_instance &instance)
registered_function &
function_builder::add_function (const function_instance &instance,
const char *name, tree fntype, tree attrs,
-	bool placeholder_p)
+	bool placeholder_p, const char *overload_name,
+	const vec<tree> &argument_types,
+	bool overloaded_p = false)
{
   unsigned int code = vec_safe_length (registered_functions);
   code = (code << RISCV_BUILTIN_SHIFT) + RISCV_BUILTIN_VECTOR;
@@ -3395,6 +3437,9 @@ function_builder::add_function (const function_instance &instance,
   registered_function &rfn = *ggc_alloc<registered_function> ();
   rfn.instance = instance;
   rfn.decl = decl;
+  rfn.overload_name = overload_name ? xstrdup (overload_name) : NULL;
+  rfn.argument_types = argument_types;
+  rfn.overloaded_p = overloaded_p;
   vec_safe_push (registered_functions, &rfn);
   return rfn;
@@ -3415,6 +3460,10 @@ function_builder::add_unique_function (const function_instance &instance,
   if (!check_required_extensions (instance))
     return;
+  /* Also add the function under its overloaded alias, if we want
+     a separate decl for each instance of an overloaded function.  */
+  char *overload_name = shape->get_name (*this, instance, true);
+
   /* Add the function under its full (unique) name.  */
   char *name = shape->get_name (*this, instance, false);
   tree fntype
@@ -3422,7 +3471,8 @@ function_builder::add_unique_function (const function_instance &instance,
argument_types.address ());
   tree attrs = get_attributes (instance);
   registered_function &rfn
-    = add_function (instance, name, fntype, attrs, false);
+    = add_function (instance, name, fntype, attrs, false, overload_name,
+	    argument_types.copy ());
   /* Enter the function into the hash table.  */
   hashval_t hash = instance.hash ();
@@ -3431,19 +3481,45 @@ function_builder::add_unique_function (const function_instance &instance,
   gcc_assert (!*rfn_slot);
   *rfn_slot = &rfn;
-  /* Also add the function under its overloaded alias, if we want
-     a separate decl for each instance of an overloaded function.  */
-  char *overload_name = shape->get_name (*this, instance, true);
   if (overload_name)
     {
       /* Attribute lists shouldn't be shared.  */
       tree attrs = get_attributes (instance);
       bool placeholder_p = !m_direct_overloads;
-      add_function (instance, overload_name, fntype, attrs, placeholder_p);
+      add_function (instance, overload_name, fntype, attrs, placeholder_p, NULL,
+	    vNULL);
+
+      /* Enter the function into the non-overloaded hash table.  */
+      hash = rfn.overloaded_hash ();
+      rfn_slot = non_overloaded_function_table->find_slot_with_hash (&rfn, hash,
+	     INSERT);
+      gcc_assert (!*rfn_slot);
+      *rfn_slot = &rfn;
     }
   obstack_free (&m_string_obstack, name);
}
+/* Add overloaded function for gcc. */
+void
+function_builder::add_overloaded_function (const function_instance &instance,
+	   const function_shape *shape)
+{
+  if (!check_required_extensions (instance))
+    return;
+
+  char *name = shape->get_name (*this, instance, true);
+
+  if (name)
+    {
+      /* To avoid API conflicting, take void return type and void argument
+	for the overloaded function.  */
+      tree fntype = build_function_type (void_type_node, void_list_node);
+      add_function (instance, name, fntype, NULL_TREE, m_direct_overloads, name,
+	    vNULL, true);
+      obstack_free (&m_string_obstack, name);
+    }
+}
+
function_call_info::function_call_info (location_t location_in,
const function_instance &instance_in,
tree fndecl_in)
@@ -3991,6 +4067,122 @@ 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)
+{
+  if (instance.base->may_require_vxrm_p ()
+      || (instance.base->may_require_frm_p ()
+	  && (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
+	      == INTEGER_TYPE)))
+    return true;
+  return false;
+}
+
+hashval_t
+registered_function::overloaded_hash (const vec<tree, va_gc> &arglist)
+{
+  argument_types = vNULL;
+  unsigned int len = arglist.length ();
+
+  for (unsigned int i = 0; i < len; i++)
+    {
+      /* vint8m1_t __riscv_vget_i8m1(vint8m2_t src, size_t index);
+	     When the user calls vget intrinsic, the __riscv_vget_i8m1(src, 1)
+       form is used. The compiler recognizes that the parameter index is signed
+       int, which is inconsistent with size_t, so the index is converted to
+       size_t type in order to get correct hash value. vint8m2_t
+       __riscv_vset(vint8m2_t dest, size_t index, vint8m1_t value); The reason
+       is the same as above. */
+      if ((instance.base == bases::vget && (i == (len - 1)))
+	  || (instance.base == bases::vset && (i == (len - 2))))
+	argument_types.safe_push (size_type_node);
+      /* Vector fixed-point arithmetic instructions requiring argument vxrm.
+	     For example: vuint32m4_t __riscv_vaaddu(vuint32m4_t vs2,
+      vuint32m4_t vs1, unsigned int vxrm, size_t vl); The user calls vaaddu
+      intrinsic in the form of __riscv_vaaddu(vs2, vs1, 2, vl). The compiler
+      recognizes that the parameter vxrm is a signed int, which is inconsistent
+      with the parameter unsigned int vxrm declared by intrinsic, so the
+      parameter vxrm is converted to an unsigned int type in order to get
+      correct hash value.
+
+      Vector Floating-Point Instructions requiring argument frm.
+      DEF_RVV_FUNCTION (vfadd, alu, full_preds, f_vvv_ops)
+      DEF_RVV_FUNCTION (vfadd_frm, alu_frm, full_preds, f_vvv_ops)
+      Taking vfadd as an example, theoretically we can add base or shape to the
+      hash value to distinguish whether the frm parameter is required.
+      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);
+      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned int
+      frm, size_t vl);
+
+	    However, the current registration mechanism of overloaded intinsic for gcc
+      limits the intrinsic obtained by entering the hook to always be vfadd, not
+      vfadd_frm. Therefore, the correct hash value cannot be obtained through the
+      parameter list and overload name, base or shape.
+      +--------+---------------------------+-------------------+
+      | index  | name                      | kind              |
+      +--------+---------------------------+-------------------+
+      | 124733 | __riscv_vfadd             | Overloaded        | <- Hook fun code
+      +--------+---------------------------+-------------------+
+      | 124735 |  __riscv_vfadd_vv_f32m1   | Non-overloaded    |
+      +--------+---------------------------+-------------------+
+      | 124737 | __riscv_vfadd             | Placeholder       |
+      +--------+---------------------------+-------------------+
+      | ...                                                    |
+      +--------+---------------------------+-------------------+
+      | ...                                                    |
+      +--------+---------------------------+-------------------+
+      | 125739 | __riscv_vfadd             | Overloaded        |
+      +--------+---------------------------+-------------------+
+      | 125741 | __riscv_vfadd_vv_f32m1_rm | Non-overloaded    |
+      +--------+---------------------------+-------------------+
+      | 125743 | __riscv_vfadd             | Placeholder       |
+      +--------+---------------------------+-------------------+
+
+	    Therefore, the hash value cannot be added with base or shape, and needs
+      to be distinguished by whether the penultimate parameter is INTEGER_TYPE. */
+      else if (has_vxrm_or_frm_p (instance, arglist) && (i == (len - 2)))
+	argument_types.safe_push (unsigned_type_node);
+      else
+	argument_types.safe_push (TREE_TYPE (arglist[i]));
+    }
+  return overloaded_hash ();
+}
+
+inline hashval_t
+non_overloaded_registered_function_hasher::hash (value_type value)
+{
+  return value->overloaded_hash ();
+}
+
+inline bool
+non_overloaded_registered_function_hasher::equal (value_type value,
+	  const compare_type &key)
+{
+  return ((strcmp (value->overload_name, key->overload_name) == 0)
+	  && value->overloaded_hash () == key->overloaded_hash ());
+}
+
/* If TYPE is a built-in type defined by the RVV ABI, return the mangled name,
    otherwise return NULL.  */
const char *
@@ -4139,7 +4331,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 +4348,8 @@ handle_pragma_vector ()
   /* Define the functions.  */
   function_table = new hash_table<registered_function_hasher> (1023);
+  non_overloaded_function_table
+    = new hash_table<non_overloaded_registered_function_hasher> (1023);
   function_builder builder;
   for (unsigned int i = 0; i < ARRAY_SIZE (function_groups); ++i)
     builder.register_function_group (function_groups[i]);
@@ -4208,6 +4402,24 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
   TREE_TYPE (rfn.decl), nargs, args).check ();
}
+tree
+resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
+{
+  if (code >= vec_safe_length (registered_functions))
+    return NULL_TREE;
+
+  registered_function *rfun = (*registered_functions)[code];
+
+  if (!rfun || !rfun->overloaded_p)
+    return NULL_TREE;
+
+  hashval_t hash = rfun->overloaded_hash (*arglist);
+  registered_function *rfn
+    = non_overloaded_function_table->find_with_hash (rfun, hash);
+  gcc_assert (rfn);
+  return rfn->decl;
+}
+
function_instance
get_read_vl_instance (void)
{
diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
index e358a8e4d91..cd8ccab1724 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.  */
@@ -417,6 +420,12 @@ public:
   /* Return true if intrinsics has rounding mode operand.  */
   virtual bool has_rounding_mode_operand_p () const;
+  /* Return true if intrinsics maybe require vxrm operand.  */
+  virtual bool may_require_vxrm_p () const;
+
+  /* Return true if intrinsics maybe require frm operand.  */
+  virtual bool may_require_frm_p () const;
+
   /* Try to fold the given gimple call.  Return the new gimple statement
      on success, otherwise return null.  */
   virtual gimple *fold (gimple_folder &) const { return NULL; }
@@ -674,6 +683,22 @@ function_base::has_rounding_mode_operand_p () const
   return false;
}
+/* We choose to return false by default since most of the intrinsics does
+   not need frm operand.  */
+inline bool
+function_base::may_require_frm_p () const
+{
+  return false;
+}
+
+/* We choose to return false by default since most of the intrinsics does
+   not need vxrm operand.  */
+inline bool
+function_base::may_require_vxrm_p () const
+{
+  return false;
+}
+
/* Since most of intrinsics can be overloaded, we set it true by default.  */
inline bool
function_base::can_be_overloaded_p (enum predication_type_index) const
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
 
 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
  2023-10-31  9:07 ` juzhe.zhong
@ 2023-10-31 11:36   ` Li Xu
  2023-10-31 12:35     ` Li, Pan2
                       ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Li Xu @ 2023-10-31 11:36 UTC (permalink / raw)
  To: juzhe.zhong; +Cc: gcc-patches, kito.cheng, palmer

All overload and non-overload intrinsics have been tested successfully on gcc and g++.

Thanks.


> -----原始邮件-----发件人:"juzhe.zhong@rivai.ai" <juzhe.zhong@rivai.ai>发送时间:2023-10-31 17:07:11 (星期二)收件人:"Li Xu" <xuli1@eswincomputing.com>, gcc-patches <gcc-patches@gcc.gnu.org>抄送:"kito.cheng" <kito.cheng@gmail.com>, palmer <palmer@dabbelt.com>, "Li Xu" <xuli1@eswincomputing.com>主题:Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
> 
> LGTM from my side.
> 
> Give kito one more day to review it.
> 
> Thanks for support this feature !
> 
> juzhe.zhong@rivai.ai
>  
> From: Li Xu
> Date: 2023-10-31 17:03
> To: gcc-patches
> CC: kito.cheng; palmer; juzhe.zhong; xuli
> Subject: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
> From: xuli <xuli1@eswincomputing.com>
>  
> Update in v6:
> * Rename maybe_require_frm_p to may_require_frm_p.
> * Rename maybe_require_vxrm_p to may_require_vxrm_p.
> * Move may_require_frm_p and may_require_vxrm_p to function_base.
>  
> Update in v5:
> * Split has_vxrm_or_frm_p into maybe_require_frm_p and
>   maybe_require_vxrm_p.
> * Adjust comments.
>  
> Update in v4:
> * Remove class function_resolver.
> * Remove function get_non_overloaded_instance.
> * Add overloaded hash traits for non-overloaded intrinsic.
> * All overloaded intrinsics are implemented, and the tests pass.
>  
> Update in v3:
>  
> * Rewrite comment for overloaded function add.
> * Move get_non_overloaded_instance to function_base.
>  
> Update in v2:
>  
> * Add get_non_overloaded_instance for function instance.
> * Fix overload check for policy function.
> * Enrich the test cases check.
>  
> Original log:
>  
> This patch would like add the framework to support the RVV overloaded
> intrinsic API in riscv-xxx-xxx-gcc, like riscv-xxx-xxx-g++ did.
>  
> However, it almost leverage the hook TARGET_RESOLVE_OVERLOADED_BUILTIN
> with below steps.
>  
> * Register overloaded functions.
> * Add function_resolver for overloaded function resolving.
> * Add resolve API for function shape with default implementation.
> * Implement HOOK for navigating the overloaded API to non-overloaded API.
>  
> gcc/ChangeLog:
>  
>         * config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): New function for the hook.
>         (riscv_register_pragmas): Register the hook.
>         * config/riscv/riscv-protos.h (resolve_overloaded_builtin): New decl.
>         * config/riscv/riscv-vector-builtins-bases.cc: New function impl.
>         * 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 (function_base::may_require_frm_p): Ditto.
>         (function_base::may_require_vxrm_p): Ditto.
>  
> 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-bases.cc      |  69 +++++-
> .../riscv/riscv-vector-builtins-shapes.cc     |   1 +
> gcc/config/riscv/riscv-vector-builtins.cc     | 226 +++++++++++++++++-
> gcc/config/riscv/riscv-vector-builtins.h      |  27 ++-
> .../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 +++
> 24 files changed, 708 insertions(+), 18 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 = &empty;
> +
> +  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-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> index 0b1409a52e0..9bc2be2a6da 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> @@ -262,7 +262,8 @@ public:
>     vremu/vsadd/vsaddu/vssub/vssubu
>     vfadd/vfsub/
> */
> -template<rtx_code CODE, enum frm_op_type FRM_OP = NO_FRM>
> +template <rtx_code CODE, bool MAY_REQUIRE_FRM = false,
> +	  enum frm_op_type FRM_OP = NO_FRM>
> class binop : public function_base
> {
> public:
> @@ -271,6 +272,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return MAY_REQUIRE_FRM; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -308,6 +311,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
> @@ -397,6 +402,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -630,6 +637,8 @@ class sat_op : public function_base
> public:
>    bool has_rounding_mode_operand_p () const override { return true; }
> +  bool may_require_vxrm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -652,6 +661,8 @@ class vnclip : public function_base
> public:
>    bool has_rounding_mode_operand_p () const override { return true; }
> +  bool may_require_vxrm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -1024,6 +1035,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1040,6 +1053,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1064,6 +1079,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1087,6 +1104,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1111,6 +1130,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1134,6 +1155,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1157,6 +1180,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1181,6 +1206,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1204,6 +1231,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1228,6 +1257,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1251,6 +1282,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1274,6 +1307,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1297,6 +1332,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1321,6 +1358,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_vf)
> @@ -1392,6 +1431,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (code_for_pred_fcvt_x_f (UNSPEC, e.arg_mode (0)));
> @@ -1418,6 +1459,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_x_v)
> @@ -1439,6 +1482,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1483,6 +1528,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1510,6 +1557,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_f_w)
> @@ -1555,6 +1604,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool apply_mask_policy_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -2164,20 +2215,20 @@ static CONSTEXPR const mask_misc<UNSPEC_VMSIF> vmsif_obj;
> static CONSTEXPR const mask_misc<UNSPEC_VMSOF> vmsof_obj;
> static CONSTEXPR const viota viota_obj;
> static CONSTEXPR const vid vid_obj;
> -static CONSTEXPR const binop<PLUS> vfadd_obj;
> -static CONSTEXPR const binop<MINUS> vfsub_obj;
> -static CONSTEXPR const binop<PLUS, HAS_FRM> vfadd_frm_obj;
> -static CONSTEXPR const binop<MINUS, HAS_FRM> vfsub_frm_obj;
> +static CONSTEXPR const binop<PLUS, true> vfadd_obj;
> +static CONSTEXPR const binop<MINUS, true> vfsub_obj;
> +static CONSTEXPR const binop<PLUS, true, HAS_FRM> vfadd_frm_obj;
> +static CONSTEXPR const binop<MINUS, true, HAS_FRM> vfsub_frm_obj;
> static CONSTEXPR const reverse_binop<MINUS> vfrsub_obj;
> static CONSTEXPR const reverse_binop<MINUS, HAS_FRM> vfrsub_frm_obj;
> static CONSTEXPR const widen_binop_fp<PLUS> vfwadd_obj;
> static CONSTEXPR const widen_binop_fp<PLUS, HAS_FRM> vfwadd_frm_obj;
> static CONSTEXPR const widen_binop_fp<MINUS> vfwsub_obj;
> static CONSTEXPR const widen_binop_fp<MINUS, HAS_FRM> vfwsub_frm_obj;
> -static CONSTEXPR const binop<MULT> vfmul_obj;
> -static CONSTEXPR const binop<MULT, HAS_FRM> vfmul_frm_obj;
> -static CONSTEXPR const binop<DIV> vfdiv_obj;
> -static CONSTEXPR const binop<DIV, HAS_FRM> vfdiv_frm_obj;
> +static CONSTEXPR const binop<MULT, true> vfmul_obj;
> +static CONSTEXPR const binop<MULT,  true, HAS_FRM> vfmul_frm_obj;
> +static CONSTEXPR const binop<DIV, true> vfdiv_obj;
> +static CONSTEXPR const binop<DIV,  true, HAS_FRM> vfdiv_frm_obj;
> static CONSTEXPR const reverse_binop<DIV> vfrdiv_obj;
> static CONSTEXPR const reverse_binop<DIV, HAS_FRM> vfrdiv_frm_obj;
> static CONSTEXPR const widen_binop_fp<MULT> vfwmul_obj;
> 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..e7564b9cf7c 100644
> --- a/gcc/config/riscv/riscv-vector-builtins.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins.cc
> @@ -80,6 +80,32 @@ public:
>    /* The decl itself.  */
>    tree GTY ((skip)) decl;
> +
> +  /* The overload hash of non-overloaded intrinsic is determined by
> +     the overload name and argument list. Adding the overload name to
> +     the hash is also to address the following situations:
> +     vint16mf4_t  __riscv_vreinterpret_i16mf4 (vfloat16mf4_t src);
> +     vuint16mf4_t __riscv_vreinterpret_u16mf4 (vfloat16mf4_t src);
> +     The base, shape and argument list of the vreinterpret instance are
> +     the same, only the overload name is different. Therefore, it is
> +     enough to add overload_name and argument list to the hash value.*/
> +  const char *overload_name;
> +
> +  /* The argument list part of the hash value. Add the unsigned/signed type
> +     and machine mode of each argument to the hash value. */
> +  vec<tree> GTY ((skip)) argument_types;
> +
> +  /* True if the decl represents an overloaded function that needs to be
> +     resolved. */
> +  bool overloaded_p;
> +
> +  /* The hash value to indicate the non-overloaded function. Generate hash value
> +     based on overload_name and argument_types. */
> +  hashval_t overloaded_hash () const;
> +
> +  /* Generate hash value based on the overload_name and the argument list passed
> +     by the user when calling. */
> +  hashval_t overloaded_hash (const vec<tree, va_gc> &);
> };
> /* Hash traits for registered_function.  */
> @@ -91,6 +117,14 @@ struct registered_function_hasher : nofree_ptr_hash<registered_function>
>    static bool equal (value_type, const compare_type &);
> };
> +/* Hash traits for overload registered_function. */
> +struct non_overloaded_registered_function_hasher
> +  : nofree_ptr_hash<registered_function>
> +{
> +  static hashval_t hash (value_type);
> +  static bool equal (value_type, const compare_type &);
> +};
> +
> /* Static information about each RVV type.  */
> static CONSTEXPR const vector_type_info vector_types[] = {
> #define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, ARGS...)                          \
> @@ -2611,6 +2645,12 @@ static GTY (()) vec<registered_function *, va_gc> *registered_functions;
>     overloaded functions.  */
> static hash_table<registered_function_hasher> *function_table;
> +/* All registered function decls, hashed on overload_name and argument list
> +   of the registered_function.  This is used for looking up implementations
> +   of non-overloaded functions. */
> +static hash_table<non_overloaded_registered_function_hasher>
> +  *non_overloaded_function_table;
> +
> /* RAII class for enabling enough RVV features to define the built-in
>     types and implement the riscv_vector.h pragma.
> @@ -3369,7 +3409,9 @@ function_builder::get_attributes (const function_instance &instance)
> registered_function &
> function_builder::add_function (const function_instance &instance,
> const char *name, tree fntype, tree attrs,
> -	bool placeholder_p)
> +	bool placeholder_p, const char *overload_name,
> +	const vec<tree> &argument_types,
> +	bool overloaded_p = false)
> {
>    unsigned int code = vec_safe_length (registered_functions);
>    code = (code << RISCV_BUILTIN_SHIFT) + RISCV_BUILTIN_VECTOR;
> @@ -3395,6 +3437,9 @@ function_builder::add_function (const function_instance &instance,
>    registered_function &rfn = *ggc_alloc<registered_function> ();
>    rfn.instance = instance;
>    rfn.decl = decl;
> +  rfn.overload_name = overload_name ? xstrdup (overload_name) : NULL;
> +  rfn.argument_types = argument_types;
> +  rfn.overloaded_p = overloaded_p;
>    vec_safe_push (registered_functions, &rfn);
>    return rfn;
> @@ -3415,6 +3460,10 @@ function_builder::add_unique_function (const function_instance &instance,
>    if (!check_required_extensions (instance))
>      return;
> +  /* Also add the function under its overloaded alias, if we want
> +     a separate decl for each instance of an overloaded function.  */
> +  char *overload_name = shape->get_name (*this, instance, true);
> +
>    /* Add the function under its full (unique) name.  */
>    char *name = shape->get_name (*this, instance, false);
>    tree fntype
> @@ -3422,7 +3471,8 @@ function_builder::add_unique_function (const function_instance &instance,
> argument_types.address ());
>    tree attrs = get_attributes (instance);
>    registered_function &rfn
> -    = add_function (instance, name, fntype, attrs, false);
> +    = add_function (instance, name, fntype, attrs, false, overload_name,
> +	    argument_types.copy ());
>    /* Enter the function into the hash table.  */
>    hashval_t hash = instance.hash ();
> @@ -3431,19 +3481,45 @@ function_builder::add_unique_function (const function_instance &instance,
>    gcc_assert (!*rfn_slot);
>    *rfn_slot = &rfn;
> -  /* Also add the function under its overloaded alias, if we want
> -     a separate decl for each instance of an overloaded function.  */
> -  char *overload_name = shape->get_name (*this, instance, true);
>    if (overload_name)
>      {
>        /* Attribute lists shouldn't be shared.  */
>        tree attrs = get_attributes (instance);
>        bool placeholder_p = !m_direct_overloads;
> -      add_function (instance, overload_name, fntype, attrs, placeholder_p);
> +      add_function (instance, overload_name, fntype, attrs, placeholder_p, NULL,
> +	    vNULL);
> +
> +      /* Enter the function into the non-overloaded hash table.  */
> +      hash = rfn.overloaded_hash ();
> +      rfn_slot = non_overloaded_function_table->find_slot_with_hash (&rfn, hash,
> +	     INSERT);
> +      gcc_assert (!*rfn_slot);
> +      *rfn_slot = &rfn;
>      }
>    obstack_free (&m_string_obstack, name);
> }
> +/* Add overloaded function for gcc. */
> +void
> +function_builder::add_overloaded_function (const function_instance &instance,
> +	   const function_shape *shape)
> +{
> +  if (!check_required_extensions (instance))
> +    return;
> +
> +  char *name = shape->get_name (*this, instance, true);
> +
> +  if (name)
> +    {
> +      /* To avoid API conflicting, take void return type and void argument
> +	for the overloaded function.  */
> +      tree fntype = build_function_type (void_type_node, void_list_node);
> +      add_function (instance, name, fntype, NULL_TREE, m_direct_overloads, name,
> +	    vNULL, true);
> +      obstack_free (&m_string_obstack, name);
> +    }
> +}
> +
> function_call_info::function_call_info (location_t location_in,
> const function_instance &instance_in,
> tree fndecl_in)
> @@ -3991,6 +4067,122 @@ 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)
> +{
> +  if (instance.base->may_require_vxrm_p ()
> +      || (instance.base->may_require_frm_p ()
> +	  && (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
> +	      == INTEGER_TYPE)))
> +    return true;
> +  return false;
> +}
> +
> +hashval_t
> +registered_function::overloaded_hash (const vec<tree, va_gc> &arglist)
> +{
> +  argument_types = vNULL;
> +  unsigned int len = arglist.length ();
> +
> +  for (unsigned int i = 0; i < len; i++)
> +    {
> +      /* vint8m1_t __riscv_vget_i8m1(vint8m2_t src, size_t index);
> +	     When the user calls vget intrinsic, the __riscv_vget_i8m1(src, 1)
> +       form is used. The compiler recognizes that the parameter index is signed
> +       int, which is inconsistent with size_t, so the index is converted to
> +       size_t type in order to get correct hash value. vint8m2_t
> +       __riscv_vset(vint8m2_t dest, size_t index, vint8m1_t value); The reason
> +       is the same as above. */
> +      if ((instance.base == bases::vget && (i == (len - 1)))
> +	  || (instance.base == bases::vset && (i == (len - 2))))
> +	argument_types.safe_push (size_type_node);
> +      /* Vector fixed-point arithmetic instructions requiring argument vxrm.
> +	     For example: vuint32m4_t __riscv_vaaddu(vuint32m4_t vs2,
> +      vuint32m4_t vs1, unsigned int vxrm, size_t vl); The user calls vaaddu
> +      intrinsic in the form of __riscv_vaaddu(vs2, vs1, 2, vl). The compiler
> +      recognizes that the parameter vxrm is a signed int, which is inconsistent
> +      with the parameter unsigned int vxrm declared by intrinsic, so the
> +      parameter vxrm is converted to an unsigned int type in order to get
> +      correct hash value.
> +
> +      Vector Floating-Point Instructions requiring argument frm.
> +      DEF_RVV_FUNCTION (vfadd, alu, full_preds, f_vvv_ops)
> +      DEF_RVV_FUNCTION (vfadd_frm, alu_frm, full_preds, f_vvv_ops)
> +      Taking vfadd as an example, theoretically we can add base or shape to the
> +      hash value to distinguish whether the frm parameter is required.
> +      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);
> +      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned int
> +      frm, size_t vl);
> +
> +	    However, the current registration mechanism of overloaded intinsic for gcc
> +      limits the intrinsic obtained by entering the hook to always be vfadd, not
> +      vfadd_frm. Therefore, the correct hash value cannot be obtained through the
> +      parameter list and overload name, base or shape.
> +      +--------+---------------------------+-------------------+
> +      | index  | name                      | kind              |
> +      +--------+---------------------------+-------------------+
> +      | 124733 | __riscv_vfadd             | Overloaded        | <- Hook fun code
> +      +--------+---------------------------+-------------------+
> +      | 124735 |  __riscv_vfadd_vv_f32m1   | Non-overloaded    |
> +      +--------+---------------------------+-------------------+
> +      | 124737 | __riscv_vfadd             | Placeholder       |
> +      +--------+---------------------------+-------------------+
> +      | ...                                                    |
> +      +--------+---------------------------+-------------------+
> +      | ...                                                    |
> +      +--------+---------------------------+-------------------+
> +      | 125739 | __riscv_vfadd             | Overloaded        |
> +      +--------+---------------------------+-------------------+
> +      | 125741 | __riscv_vfadd_vv_f32m1_rm | Non-overloaded    |
> +      +--------+---------------------------+-------------------+
> +      | 125743 | __riscv_vfadd             | Placeholder       |
> +      +--------+---------------------------+-------------------+
> +
> +	    Therefore, the hash value cannot be added with base or shape, and needs
> +      to be distinguished by whether the penultimate parameter is INTEGER_TYPE. */
> +      else if (has_vxrm_or_frm_p (instance, arglist) && (i == (len - 2)))
> +	argument_types.safe_push (unsigned_type_node);
> +      else
> +	argument_types.safe_push (TREE_TYPE (arglist[i]));
> +    }
> +  return overloaded_hash ();
> +}
> +
> +inline hashval_t
> +non_overloaded_registered_function_hasher::hash (value_type value)
> +{
> +  return value->overloaded_hash ();
> +}
> +
> +inline bool
> +non_overloaded_registered_function_hasher::equal (value_type value,
> +	  const compare_type &key)
> +{
> +  return ((strcmp (value->overload_name, key->overload_name) == 0)
> +	  && value->overloaded_hash () == key->overloaded_hash ());
> +}
> +
> /* If TYPE is a built-in type defined by the RVV ABI, return the mangled name,
>     otherwise return NULL.  */
> const char *
> @@ -4139,7 +4331,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 +4348,8 @@ handle_pragma_vector ()
>    /* Define the functions.  */
>    function_table = new hash_table<registered_function_hasher> (1023);
> +  non_overloaded_function_table
> +    = new hash_table<non_overloaded_registered_function_hasher> (1023);
>    function_builder builder;
>    for (unsigned int i = 0; i < ARRAY_SIZE (function_groups); ++i)
>      builder.register_function_group (function_groups[i]);
> @@ -4208,6 +4402,24 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
>    TREE_TYPE (rfn.decl), nargs, args).check ();
> }
> +tree
> +resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
> +{
> +  if (code >= vec_safe_length (registered_functions))
> +    return NULL_TREE;
> +
> +  registered_function *rfun = (*registered_functions)[code];
> +
> +  if (!rfun || !rfun->overloaded_p)
> +    return NULL_TREE;
> +
> +  hashval_t hash = rfun->overloaded_hash (*arglist);
> +  registered_function *rfn
> +    = non_overloaded_function_table->find_with_hash (rfun, hash);
> +  gcc_assert (rfn);
> +  return rfn->decl;
> +}
> +
> function_instance
> get_read_vl_instance (void)
> {
> diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
> index e358a8e4d91..cd8ccab1724 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.  */
> @@ -417,6 +420,12 @@ public:
>    /* Return true if intrinsics has rounding mode operand.  */
>    virtual bool has_rounding_mode_operand_p () const;
> +  /* Return true if intrinsics maybe require vxrm operand.  */
> +  virtual bool may_require_vxrm_p () const;
> +
> +  /* Return true if intrinsics maybe require frm operand.  */
> +  virtual bool may_require_frm_p () const;
> +
>    /* Try to fold the given gimple call.  Return the new gimple statement
>       on success, otherwise return null.  */
>    virtual gimple *fold (gimple_folder &) const { return NULL; }
> @@ -674,6 +683,22 @@ function_base::has_rounding_mode_operand_p () const
>    return false;
> }
> +/* We choose to return false by default since most of the intrinsics does
> +   not need frm operand.  */
> +inline bool
> +function_base::may_require_frm_p () const
> +{
> +  return false;
> +}
> +
> +/* We choose to return false by default since most of the intrinsics does
> +   not need vxrm operand.  */
> +inline bool
> +function_base::may_require_vxrm_p () const
> +{
> +  return false;
> +}
> +
> /* Since most of intrinsics can be overloaded, we set it true by default.  */
> inline bool
> function_base::can_be_overloaded_p (enum predication_type_index) const
> 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
>  
>  

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
  2023-10-31 11:36   ` Li Xu
@ 2023-10-31 12:35     ` Li, Pan2
  2023-11-01  0:26     ` juzhe.zhong
  2023-11-06  1:26     ` juzhe.zhong
  2 siblings, 0 replies; 7+ messages in thread
From: Li, Pan2 @ 2023-10-31 12:35 UTC (permalink / raw)
  To: Li Xu, juzhe.zhong; +Cc: gcc-patches, kito.cheng, palmer

Thanks xuli for enabling this feature, we can update the CI of rvv-intrinsic-doc for overloaded API(s) after committed.

Pan

-----Original Message-----
From: Li Xu <xuli1@eswincomputing.com> 
Sent: Tuesday, October 31, 2023 7:37 PM
To: juzhe.zhong@rivai.ai
Cc: gcc-patches <gcc-patches@gcc.gnu.org>; kito.cheng <kito.cheng@gmail.com>; palmer <palmer@dabbelt.com>
Subject: Re: Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic

All overload and non-overload intrinsics have been tested successfully on gcc and g++.

Thanks.


> -----原始邮件-----发件人:"juzhe.zhong@rivai.ai" <juzhe.zhong@rivai.ai>发送时间:2023-10-31 17:07:11 (星期二)收件人:"Li Xu" <xuli1@eswincomputing.com>, gcc-patches <gcc-patches@gcc.gnu.org>抄送:"kito.cheng" <kito.cheng@gmail.com>, palmer <palmer@dabbelt.com>, "Li Xu" <xuli1@eswincomputing.com>主题:Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
> 
> LGTM from my side.
> 
> Give kito one more day to review it.
> 
> Thanks for support this feature !
> 
> juzhe.zhong@rivai.ai
>  
> From: Li Xu
> Date: 2023-10-31 17:03
> To: gcc-patches
> CC: kito.cheng; palmer; juzhe.zhong; xuli
> Subject: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
> From: xuli <xuli1@eswincomputing.com>
>  
> Update in v6:
> * Rename maybe_require_frm_p to may_require_frm_p.
> * Rename maybe_require_vxrm_p to may_require_vxrm_p.
> * Move may_require_frm_p and may_require_vxrm_p to function_base.
>  
> Update in v5:
> * Split has_vxrm_or_frm_p into maybe_require_frm_p and
>   maybe_require_vxrm_p.
> * Adjust comments.
>  
> Update in v4:
> * Remove class function_resolver.
> * Remove function get_non_overloaded_instance.
> * Add overloaded hash traits for non-overloaded intrinsic.
> * All overloaded intrinsics are implemented, and the tests pass.
>  
> Update in v3:
>  
> * Rewrite comment for overloaded function add.
> * Move get_non_overloaded_instance to function_base.
>  
> Update in v2:
>  
> * Add get_non_overloaded_instance for function instance.
> * Fix overload check for policy function.
> * Enrich the test cases check.
>  
> Original log:
>  
> This patch would like add the framework to support the RVV overloaded
> intrinsic API in riscv-xxx-xxx-gcc, like riscv-xxx-xxx-g++ did.
>  
> However, it almost leverage the hook TARGET_RESOLVE_OVERLOADED_BUILTIN
> with below steps.
>  
> * Register overloaded functions.
> * Add function_resolver for overloaded function resolving.
> * Add resolve API for function shape with default implementation.
> * Implement HOOK for navigating the overloaded API to non-overloaded API.
>  
> gcc/ChangeLog:
>  
>         * config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): New function for the hook.
>         (riscv_register_pragmas): Register the hook.
>         * config/riscv/riscv-protos.h (resolve_overloaded_builtin): New decl.
>         * config/riscv/riscv-vector-builtins-bases.cc: New function impl.
>         * 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 (function_base::may_require_frm_p): Ditto.
>         (function_base::may_require_vxrm_p): Ditto.
>  
> 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-bases.cc      |  69 +++++-
> .../riscv/riscv-vector-builtins-shapes.cc     |   1 +
> gcc/config/riscv/riscv-vector-builtins.cc     | 226 +++++++++++++++++-
> gcc/config/riscv/riscv-vector-builtins.h      |  27 ++-
> .../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 +++
> 24 files changed, 708 insertions(+), 18 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 = &empty;
> +
> +  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-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> index 0b1409a52e0..9bc2be2a6da 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> @@ -262,7 +262,8 @@ public:
>     vremu/vsadd/vsaddu/vssub/vssubu
>     vfadd/vfsub/
> */
> -template<rtx_code CODE, enum frm_op_type FRM_OP = NO_FRM>
> +template <rtx_code CODE, bool MAY_REQUIRE_FRM = false,
> +	  enum frm_op_type FRM_OP = NO_FRM>
> class binop : public function_base
> {
> public:
> @@ -271,6 +272,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return MAY_REQUIRE_FRM; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -308,6 +311,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
> @@ -397,6 +402,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -630,6 +637,8 @@ class sat_op : public function_base
> public:
>    bool has_rounding_mode_operand_p () const override { return true; }
> +  bool may_require_vxrm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -652,6 +661,8 @@ class vnclip : public function_base
> public:
>    bool has_rounding_mode_operand_p () const override { return true; }
> +  bool may_require_vxrm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -1024,6 +1035,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1040,6 +1053,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1064,6 +1079,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1087,6 +1104,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1111,6 +1130,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1134,6 +1155,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1157,6 +1180,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1181,6 +1206,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1204,6 +1231,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1228,6 +1257,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1251,6 +1282,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1274,6 +1307,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1297,6 +1332,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1321,6 +1358,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_vf)
> @@ -1392,6 +1431,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (code_for_pred_fcvt_x_f (UNSPEC, e.arg_mode (0)));
> @@ -1418,6 +1459,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_x_v)
> @@ -1439,6 +1482,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1483,6 +1528,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1510,6 +1557,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_f_w)
> @@ -1555,6 +1604,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool apply_mask_policy_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -2164,20 +2215,20 @@ static CONSTEXPR const mask_misc<UNSPEC_VMSIF> vmsif_obj;
> static CONSTEXPR const mask_misc<UNSPEC_VMSOF> vmsof_obj;
> static CONSTEXPR const viota viota_obj;
> static CONSTEXPR const vid vid_obj;
> -static CONSTEXPR const binop<PLUS> vfadd_obj;
> -static CONSTEXPR const binop<MINUS> vfsub_obj;
> -static CONSTEXPR const binop<PLUS, HAS_FRM> vfadd_frm_obj;
> -static CONSTEXPR const binop<MINUS, HAS_FRM> vfsub_frm_obj;
> +static CONSTEXPR const binop<PLUS, true> vfadd_obj;
> +static CONSTEXPR const binop<MINUS, true> vfsub_obj;
> +static CONSTEXPR const binop<PLUS, true, HAS_FRM> vfadd_frm_obj;
> +static CONSTEXPR const binop<MINUS, true, HAS_FRM> vfsub_frm_obj;
> static CONSTEXPR const reverse_binop<MINUS> vfrsub_obj;
> static CONSTEXPR const reverse_binop<MINUS, HAS_FRM> vfrsub_frm_obj;
> static CONSTEXPR const widen_binop_fp<PLUS> vfwadd_obj;
> static CONSTEXPR const widen_binop_fp<PLUS, HAS_FRM> vfwadd_frm_obj;
> static CONSTEXPR const widen_binop_fp<MINUS> vfwsub_obj;
> static CONSTEXPR const widen_binop_fp<MINUS, HAS_FRM> vfwsub_frm_obj;
> -static CONSTEXPR const binop<MULT> vfmul_obj;
> -static CONSTEXPR const binop<MULT, HAS_FRM> vfmul_frm_obj;
> -static CONSTEXPR const binop<DIV> vfdiv_obj;
> -static CONSTEXPR const binop<DIV, HAS_FRM> vfdiv_frm_obj;
> +static CONSTEXPR const binop<MULT, true> vfmul_obj;
> +static CONSTEXPR const binop<MULT,  true, HAS_FRM> vfmul_frm_obj;
> +static CONSTEXPR const binop<DIV, true> vfdiv_obj;
> +static CONSTEXPR const binop<DIV,  true, HAS_FRM> vfdiv_frm_obj;
> static CONSTEXPR const reverse_binop<DIV> vfrdiv_obj;
> static CONSTEXPR const reverse_binop<DIV, HAS_FRM> vfrdiv_frm_obj;
> static CONSTEXPR const widen_binop_fp<MULT> vfwmul_obj;
> 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..e7564b9cf7c 100644
> --- a/gcc/config/riscv/riscv-vector-builtins.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins.cc
> @@ -80,6 +80,32 @@ public:
>    /* The decl itself.  */
>    tree GTY ((skip)) decl;
> +
> +  /* The overload hash of non-overloaded intrinsic is determined by
> +     the overload name and argument list. Adding the overload name to
> +     the hash is also to address the following situations:
> +     vint16mf4_t  __riscv_vreinterpret_i16mf4 (vfloat16mf4_t src);
> +     vuint16mf4_t __riscv_vreinterpret_u16mf4 (vfloat16mf4_t src);
> +     The base, shape and argument list of the vreinterpret instance are
> +     the same, only the overload name is different. Therefore, it is
> +     enough to add overload_name and argument list to the hash value.*/
> +  const char *overload_name;
> +
> +  /* The argument list part of the hash value. Add the unsigned/signed type
> +     and machine mode of each argument to the hash value. */
> +  vec<tree> GTY ((skip)) argument_types;
> +
> +  /* True if the decl represents an overloaded function that needs to be
> +     resolved. */
> +  bool overloaded_p;
> +
> +  /* The hash value to indicate the non-overloaded function. Generate hash value
> +     based on overload_name and argument_types. */
> +  hashval_t overloaded_hash () const;
> +
> +  /* Generate hash value based on the overload_name and the argument list passed
> +     by the user when calling. */
> +  hashval_t overloaded_hash (const vec<tree, va_gc> &);
> };
> /* Hash traits for registered_function.  */
> @@ -91,6 +117,14 @@ struct registered_function_hasher : nofree_ptr_hash<registered_function>
>    static bool equal (value_type, const compare_type &);
> };
> +/* Hash traits for overload registered_function. */
> +struct non_overloaded_registered_function_hasher
> +  : nofree_ptr_hash<registered_function>
> +{
> +  static hashval_t hash (value_type);
> +  static bool equal (value_type, const compare_type &);
> +};
> +
> /* Static information about each RVV type.  */
> static CONSTEXPR const vector_type_info vector_types[] = {
> #define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, ARGS...)                          \
> @@ -2611,6 +2645,12 @@ static GTY (()) vec<registered_function *, va_gc> *registered_functions;
>     overloaded functions.  */
> static hash_table<registered_function_hasher> *function_table;
> +/* All registered function decls, hashed on overload_name and argument list
> +   of the registered_function.  This is used for looking up implementations
> +   of non-overloaded functions. */
> +static hash_table<non_overloaded_registered_function_hasher>
> +  *non_overloaded_function_table;
> +
> /* RAII class for enabling enough RVV features to define the built-in
>     types and implement the riscv_vector.h pragma.
> @@ -3369,7 +3409,9 @@ function_builder::get_attributes (const function_instance &instance)
> registered_function &
> function_builder::add_function (const function_instance &instance,
> const char *name, tree fntype, tree attrs,
> -	bool placeholder_p)
> +	bool placeholder_p, const char *overload_name,
> +	const vec<tree> &argument_types,
> +	bool overloaded_p = false)
> {
>    unsigned int code = vec_safe_length (registered_functions);
>    code = (code << RISCV_BUILTIN_SHIFT) + RISCV_BUILTIN_VECTOR;
> @@ -3395,6 +3437,9 @@ function_builder::add_function (const function_instance &instance,
>    registered_function &rfn = *ggc_alloc<registered_function> ();
>    rfn.instance = instance;
>    rfn.decl = decl;
> +  rfn.overload_name = overload_name ? xstrdup (overload_name) : NULL;
> +  rfn.argument_types = argument_types;
> +  rfn.overloaded_p = overloaded_p;
>    vec_safe_push (registered_functions, &rfn);
>    return rfn;
> @@ -3415,6 +3460,10 @@ function_builder::add_unique_function (const function_instance &instance,
>    if (!check_required_extensions (instance))
>      return;
> +  /* Also add the function under its overloaded alias, if we want
> +     a separate decl for each instance of an overloaded function.  */
> +  char *overload_name = shape->get_name (*this, instance, true);
> +
>    /* Add the function under its full (unique) name.  */
>    char *name = shape->get_name (*this, instance, false);
>    tree fntype
> @@ -3422,7 +3471,8 @@ function_builder::add_unique_function (const function_instance &instance,
> argument_types.address ());
>    tree attrs = get_attributes (instance);
>    registered_function &rfn
> -    = add_function (instance, name, fntype, attrs, false);
> +    = add_function (instance, name, fntype, attrs, false, overload_name,
> +	    argument_types.copy ());
>    /* Enter the function into the hash table.  */
>    hashval_t hash = instance.hash ();
> @@ -3431,19 +3481,45 @@ function_builder::add_unique_function (const function_instance &instance,
>    gcc_assert (!*rfn_slot);
>    *rfn_slot = &rfn;
> -  /* Also add the function under its overloaded alias, if we want
> -     a separate decl for each instance of an overloaded function.  */
> -  char *overload_name = shape->get_name (*this, instance, true);
>    if (overload_name)
>      {
>        /* Attribute lists shouldn't be shared.  */
>        tree attrs = get_attributes (instance);
>        bool placeholder_p = !m_direct_overloads;
> -      add_function (instance, overload_name, fntype, attrs, placeholder_p);
> +      add_function (instance, overload_name, fntype, attrs, placeholder_p, NULL,
> +	    vNULL);
> +
> +      /* Enter the function into the non-overloaded hash table.  */
> +      hash = rfn.overloaded_hash ();
> +      rfn_slot = non_overloaded_function_table->find_slot_with_hash (&rfn, hash,
> +	     INSERT);
> +      gcc_assert (!*rfn_slot);
> +      *rfn_slot = &rfn;
>      }
>    obstack_free (&m_string_obstack, name);
> }
> +/* Add overloaded function for gcc. */
> +void
> +function_builder::add_overloaded_function (const function_instance &instance,
> +	   const function_shape *shape)
> +{
> +  if (!check_required_extensions (instance))
> +    return;
> +
> +  char *name = shape->get_name (*this, instance, true);
> +
> +  if (name)
> +    {
> +      /* To avoid API conflicting, take void return type and void argument
> +	for the overloaded function.  */
> +      tree fntype = build_function_type (void_type_node, void_list_node);
> +      add_function (instance, name, fntype, NULL_TREE, m_direct_overloads, name,
> +	    vNULL, true);
> +      obstack_free (&m_string_obstack, name);
> +    }
> +}
> +
> function_call_info::function_call_info (location_t location_in,
> const function_instance &instance_in,
> tree fndecl_in)
> @@ -3991,6 +4067,122 @@ 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)
> +{
> +  if (instance.base->may_require_vxrm_p ()
> +      || (instance.base->may_require_frm_p ()
> +	  && (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
> +	      == INTEGER_TYPE)))
> +    return true;
> +  return false;
> +}
> +
> +hashval_t
> +registered_function::overloaded_hash (const vec<tree, va_gc> &arglist)
> +{
> +  argument_types = vNULL;
> +  unsigned int len = arglist.length ();
> +
> +  for (unsigned int i = 0; i < len; i++)
> +    {
> +      /* vint8m1_t __riscv_vget_i8m1(vint8m2_t src, size_t index);
> +	     When the user calls vget intrinsic, the __riscv_vget_i8m1(src, 1)
> +       form is used. The compiler recognizes that the parameter index is signed
> +       int, which is inconsistent with size_t, so the index is converted to
> +       size_t type in order to get correct hash value. vint8m2_t
> +       __riscv_vset(vint8m2_t dest, size_t index, vint8m1_t value); The reason
> +       is the same as above. */
> +      if ((instance.base == bases::vget && (i == (len - 1)))
> +	  || (instance.base == bases::vset && (i == (len - 2))))
> +	argument_types.safe_push (size_type_node);
> +      /* Vector fixed-point arithmetic instructions requiring argument vxrm.
> +	     For example: vuint32m4_t __riscv_vaaddu(vuint32m4_t vs2,
> +      vuint32m4_t vs1, unsigned int vxrm, size_t vl); The user calls vaaddu
> +      intrinsic in the form of __riscv_vaaddu(vs2, vs1, 2, vl). The compiler
> +      recognizes that the parameter vxrm is a signed int, which is inconsistent
> +      with the parameter unsigned int vxrm declared by intrinsic, so the
> +      parameter vxrm is converted to an unsigned int type in order to get
> +      correct hash value.
> +
> +      Vector Floating-Point Instructions requiring argument frm.
> +      DEF_RVV_FUNCTION (vfadd, alu, full_preds, f_vvv_ops)
> +      DEF_RVV_FUNCTION (vfadd_frm, alu_frm, full_preds, f_vvv_ops)
> +      Taking vfadd as an example, theoretically we can add base or shape to the
> +      hash value to distinguish whether the frm parameter is required.
> +      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);
> +      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned int
> +      frm, size_t vl);
> +
> +	    However, the current registration mechanism of overloaded intinsic for gcc
> +      limits the intrinsic obtained by entering the hook to always be vfadd, not
> +      vfadd_frm. Therefore, the correct hash value cannot be obtained through the
> +      parameter list and overload name, base or shape.
> +      +--------+---------------------------+-------------------+
> +      | index  | name                      | kind              |
> +      +--------+---------------------------+-------------------+
> +      | 124733 | __riscv_vfadd             | Overloaded        | <- Hook fun code
> +      +--------+---------------------------+-------------------+
> +      | 124735 |  __riscv_vfadd_vv_f32m1   | Non-overloaded    |
> +      +--------+---------------------------+-------------------+
> +      | 124737 | __riscv_vfadd             | Placeholder       |
> +      +--------+---------------------------+-------------------+
> +      | ...                                                    |
> +      +--------+---------------------------+-------------------+
> +      | ...                                                    |
> +      +--------+---------------------------+-------------------+
> +      | 125739 | __riscv_vfadd             | Overloaded        |
> +      +--------+---------------------------+-------------------+
> +      | 125741 | __riscv_vfadd_vv_f32m1_rm | Non-overloaded    |
> +      +--------+---------------------------+-------------------+
> +      | 125743 | __riscv_vfadd             | Placeholder       |
> +      +--------+---------------------------+-------------------+
> +
> +	    Therefore, the hash value cannot be added with base or shape, and needs
> +      to be distinguished by whether the penultimate parameter is INTEGER_TYPE. */
> +      else if (has_vxrm_or_frm_p (instance, arglist) && (i == (len - 2)))
> +	argument_types.safe_push (unsigned_type_node);
> +      else
> +	argument_types.safe_push (TREE_TYPE (arglist[i]));
> +    }
> +  return overloaded_hash ();
> +}
> +
> +inline hashval_t
> +non_overloaded_registered_function_hasher::hash (value_type value)
> +{
> +  return value->overloaded_hash ();
> +}
> +
> +inline bool
> +non_overloaded_registered_function_hasher::equal (value_type value,
> +	  const compare_type &key)
> +{
> +  return ((strcmp (value->overload_name, key->overload_name) == 0)
> +	  && value->overloaded_hash () == key->overloaded_hash ());
> +}
> +
> /* If TYPE is a built-in type defined by the RVV ABI, return the mangled name,
>     otherwise return NULL.  */
> const char *
> @@ -4139,7 +4331,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 +4348,8 @@ handle_pragma_vector ()
>    /* Define the functions.  */
>    function_table = new hash_table<registered_function_hasher> (1023);
> +  non_overloaded_function_table
> +    = new hash_table<non_overloaded_registered_function_hasher> (1023);
>    function_builder builder;
>    for (unsigned int i = 0; i < ARRAY_SIZE (function_groups); ++i)
>      builder.register_function_group (function_groups[i]);
> @@ -4208,6 +4402,24 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
>    TREE_TYPE (rfn.decl), nargs, args).check ();
> }
> +tree
> +resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
> +{
> +  if (code >= vec_safe_length (registered_functions))
> +    return NULL_TREE;
> +
> +  registered_function *rfun = (*registered_functions)[code];
> +
> +  if (!rfun || !rfun->overloaded_p)
> +    return NULL_TREE;
> +
> +  hashval_t hash = rfun->overloaded_hash (*arglist);
> +  registered_function *rfn
> +    = non_overloaded_function_table->find_with_hash (rfun, hash);
> +  gcc_assert (rfn);
> +  return rfn->decl;
> +}
> +
> function_instance
> get_read_vl_instance (void)
> {
> diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
> index e358a8e4d91..cd8ccab1724 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.  */
> @@ -417,6 +420,12 @@ public:
>    /* Return true if intrinsics has rounding mode operand.  */
>    virtual bool has_rounding_mode_operand_p () const;
> +  /* Return true if intrinsics maybe require vxrm operand.  */
> +  virtual bool may_require_vxrm_p () const;
> +
> +  /* Return true if intrinsics maybe require frm operand.  */
> +  virtual bool may_require_frm_p () const;
> +
>    /* Try to fold the given gimple call.  Return the new gimple statement
>       on success, otherwise return null.  */
>    virtual gimple *fold (gimple_folder &) const { return NULL; }
> @@ -674,6 +683,22 @@ function_base::has_rounding_mode_operand_p () const
>    return false;
> }
> +/* We choose to return false by default since most of the intrinsics does
> +   not need frm operand.  */
> +inline bool
> +function_base::may_require_frm_p () const
> +{
> +  return false;
> +}
> +
> +/* We choose to return false by default since most of the intrinsics does
> +   not need vxrm operand.  */
> +inline bool
> +function_base::may_require_vxrm_p () const
> +{
> +  return false;
> +}
> +
> /* Since most of intrinsics can be overloaded, we set it true by default.  */
> inline bool
> function_base::can_be_overloaded_p (enum predication_type_index) const
> 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
>  
>  

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
  2023-10-31 11:36   ` Li Xu
  2023-10-31 12:35     ` Li, Pan2
@ 2023-11-01  0:26     ` juzhe.zhong
  2023-11-06  1:26     ` juzhe.zhong
  2 siblings, 0 replies; 7+ messages in thread
From: juzhe.zhong @ 2023-11-01  0:26 UTC (permalink / raw)
  To: Li Xu; +Cc: gcc-patches, kito.cheng, palmer

[-- Attachment #1: Type: text/plain, Size: 60794 bytes --]

Thanks LiXu.

Hi, kito. Could you review this patch ?



juzhe.zhong@rivai.ai
 
From: Li Xu
Date: 2023-10-31 19:36
To: juzhe.zhong@rivai.ai
CC: gcc-patches; kito.cheng; palmer
Subject: Re: Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
All overload and non-overload intrinsics have been tested successfully on gcc and g++.
 
Thanks.
 
 
> -----原始邮件-----发件人:"juzhe.zhong@rivai.ai" <juzhe.zhong@rivai.ai>发送时间:2023-10-31 17:07:11 (星期二)收件人:"Li Xu" <xuli1@eswincomputing.com>, gcc-patches <gcc-patches@gcc.gnu.org>抄送:"kito.cheng" <kito.cheng@gmail.com>, palmer <palmer@dabbelt.com>, "Li Xu" <xuli1@eswincomputing.com>主题:Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
> 
> LGTM from my side.
> 
> Give kito one more day to review it.
> 
> Thanks for support this feature !
> 
> juzhe.zhong@rivai.ai
>  
> From: Li Xu
> Date: 2023-10-31 17:03
> To: gcc-patches
> CC: kito.cheng; palmer; juzhe.zhong; xuli
> Subject: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
> From: xuli <xuli1@eswincomputing.com>
>  
> Update in v6:
> * Rename maybe_require_frm_p to may_require_frm_p.
> * Rename maybe_require_vxrm_p to may_require_vxrm_p.
> * Move may_require_frm_p and may_require_vxrm_p to function_base.
>  
> Update in v5:
> * Split has_vxrm_or_frm_p into maybe_require_frm_p and
>   maybe_require_vxrm_p.
> * Adjust comments.
>  
> Update in v4:
> * Remove class function_resolver.
> * Remove function get_non_overloaded_instance.
> * Add overloaded hash traits for non-overloaded intrinsic.
> * All overloaded intrinsics are implemented, and the tests pass.
>  
> Update in v3:
>  
> * Rewrite comment for overloaded function add.
> * Move get_non_overloaded_instance to function_base.
>  
> Update in v2:
>  
> * Add get_non_overloaded_instance for function instance.
> * Fix overload check for policy function.
> * Enrich the test cases check.
>  
> Original log:
>  
> This patch would like add the framework to support the RVV overloaded
> intrinsic API in riscv-xxx-xxx-gcc, like riscv-xxx-xxx-g++ did.
>  
> However, it almost leverage the hook TARGET_RESOLVE_OVERLOADED_BUILTIN
> with below steps.
>  
> * Register overloaded functions.
> * Add function_resolver for overloaded function resolving.
> * Add resolve API for function shape with default implementation.
> * Implement HOOK for navigating the overloaded API to non-overloaded API.
>  
> gcc/ChangeLog:
>  
>         * config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): New function for the hook.
>         (riscv_register_pragmas): Register the hook.
>         * config/riscv/riscv-protos.h (resolve_overloaded_builtin): New decl.
>         * config/riscv/riscv-vector-builtins-bases.cc: New function impl.
>         * 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 (function_base::may_require_frm_p): Ditto.
>         (function_base::may_require_vxrm_p): Ditto.
>  
> 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-bases.cc      |  69 +++++-
> .../riscv/riscv-vector-builtins-shapes.cc     |   1 +
> gcc/config/riscv/riscv-vector-builtins.cc     | 226 +++++++++++++++++-
> gcc/config/riscv/riscv-vector-builtins.h      |  27 ++-
> .../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 +++
> 24 files changed, 708 insertions(+), 18 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 = &empty;
> +
> +  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-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> index 0b1409a52e0..9bc2be2a6da 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> @@ -262,7 +262,8 @@ public:
>     vremu/vsadd/vsaddu/vssub/vssubu
>     vfadd/vfsub/
> */
> -template<rtx_code CODE, enum frm_op_type FRM_OP = NO_FRM>
> +template <rtx_code CODE, bool MAY_REQUIRE_FRM = false,
> +   enum frm_op_type FRM_OP = NO_FRM>
> class binop : public function_base
> {
> public:
> @@ -271,6 +272,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return MAY_REQUIRE_FRM; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -308,6 +311,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
> @@ -397,6 +402,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -630,6 +637,8 @@ class sat_op : public function_base
> public:
>    bool has_rounding_mode_operand_p () const override { return true; }
> +  bool may_require_vxrm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -652,6 +661,8 @@ class vnclip : public function_base
> public:
>    bool has_rounding_mode_operand_p () const override { return true; }
> +  bool may_require_vxrm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -1024,6 +1035,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1040,6 +1053,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1064,6 +1079,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1087,6 +1104,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1111,6 +1130,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1134,6 +1155,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1157,6 +1180,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1181,6 +1206,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1204,6 +1231,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1228,6 +1257,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1251,6 +1282,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1274,6 +1307,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1297,6 +1332,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1321,6 +1358,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_vf)
> @@ -1392,6 +1431,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (code_for_pred_fcvt_x_f (UNSPEC, e.arg_mode (0)));
> @@ -1418,6 +1459,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_x_v)
> @@ -1439,6 +1482,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1483,6 +1528,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1510,6 +1557,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_f_w)
> @@ -1555,6 +1604,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool apply_mask_policy_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -2164,20 +2215,20 @@ static CONSTEXPR const mask_misc<UNSPEC_VMSIF> vmsif_obj;
> static CONSTEXPR const mask_misc<UNSPEC_VMSOF> vmsof_obj;
> static CONSTEXPR const viota viota_obj;
> static CONSTEXPR const vid vid_obj;
> -static CONSTEXPR const binop<PLUS> vfadd_obj;
> -static CONSTEXPR const binop<MINUS> vfsub_obj;
> -static CONSTEXPR const binop<PLUS, HAS_FRM> vfadd_frm_obj;
> -static CONSTEXPR const binop<MINUS, HAS_FRM> vfsub_frm_obj;
> +static CONSTEXPR const binop<PLUS, true> vfadd_obj;
> +static CONSTEXPR const binop<MINUS, true> vfsub_obj;
> +static CONSTEXPR const binop<PLUS, true, HAS_FRM> vfadd_frm_obj;
> +static CONSTEXPR const binop<MINUS, true, HAS_FRM> vfsub_frm_obj;
> static CONSTEXPR const reverse_binop<MINUS> vfrsub_obj;
> static CONSTEXPR const reverse_binop<MINUS, HAS_FRM> vfrsub_frm_obj;
> static CONSTEXPR const widen_binop_fp<PLUS> vfwadd_obj;
> static CONSTEXPR const widen_binop_fp<PLUS, HAS_FRM> vfwadd_frm_obj;
> static CONSTEXPR const widen_binop_fp<MINUS> vfwsub_obj;
> static CONSTEXPR const widen_binop_fp<MINUS, HAS_FRM> vfwsub_frm_obj;
> -static CONSTEXPR const binop<MULT> vfmul_obj;
> -static CONSTEXPR const binop<MULT, HAS_FRM> vfmul_frm_obj;
> -static CONSTEXPR const binop<DIV> vfdiv_obj;
> -static CONSTEXPR const binop<DIV, HAS_FRM> vfdiv_frm_obj;
> +static CONSTEXPR const binop<MULT, true> vfmul_obj;
> +static CONSTEXPR const binop<MULT,  true, HAS_FRM> vfmul_frm_obj;
> +static CONSTEXPR const binop<DIV, true> vfdiv_obj;
> +static CONSTEXPR const binop<DIV,  true, HAS_FRM> vfdiv_frm_obj;
> static CONSTEXPR const reverse_binop<DIV> vfrdiv_obj;
> static CONSTEXPR const reverse_binop<DIV, HAS_FRM> vfrdiv_frm_obj;
> static CONSTEXPR const widen_binop_fp<MULT> vfwmul_obj;
> 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..e7564b9cf7c 100644
> --- a/gcc/config/riscv/riscv-vector-builtins.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins.cc
> @@ -80,6 +80,32 @@ public:
>    /* The decl itself.  */
>    tree GTY ((skip)) decl;
> +
> +  /* The overload hash of non-overloaded intrinsic is determined by
> +     the overload name and argument list. Adding the overload name to
> +     the hash is also to address the following situations:
> +     vint16mf4_t  __riscv_vreinterpret_i16mf4 (vfloat16mf4_t src);
> +     vuint16mf4_t __riscv_vreinterpret_u16mf4 (vfloat16mf4_t src);
> +     The base, shape and argument list of the vreinterpret instance are
> +     the same, only the overload name is different. Therefore, it is
> +     enough to add overload_name and argument list to the hash value.*/
> +  const char *overload_name;
> +
> +  /* The argument list part of the hash value. Add the unsigned/signed type
> +     and machine mode of each argument to the hash value. */
> +  vec<tree> GTY ((skip)) argument_types;
> +
> +  /* True if the decl represents an overloaded function that needs to be
> +     resolved. */
> +  bool overloaded_p;
> +
> +  /* The hash value to indicate the non-overloaded function. Generate hash value
> +     based on overload_name and argument_types. */
> +  hashval_t overloaded_hash () const;
> +
> +  /* Generate hash value based on the overload_name and the argument list passed
> +     by the user when calling. */
> +  hashval_t overloaded_hash (const vec<tree, va_gc> &);
> };
> /* Hash traits for registered_function.  */
> @@ -91,6 +117,14 @@ struct registered_function_hasher : nofree_ptr_hash<registered_function>
>    static bool equal (value_type, const compare_type &);
> };
> +/* Hash traits for overload registered_function. */
> +struct non_overloaded_registered_function_hasher
> +  : nofree_ptr_hash<registered_function>
> +{
> +  static hashval_t hash (value_type);
> +  static bool equal (value_type, const compare_type &);
> +};
> +
> /* Static information about each RVV type.  */
> static CONSTEXPR const vector_type_info vector_types[] = {
> #define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, ARGS...)                          \
> @@ -2611,6 +2645,12 @@ static GTY (()) vec<registered_function *, va_gc> *registered_functions;
>     overloaded functions.  */
> static hash_table<registered_function_hasher> *function_table;
> +/* All registered function decls, hashed on overload_name and argument list
> +   of the registered_function.  This is used for looking up implementations
> +   of non-overloaded functions. */
> +static hash_table<non_overloaded_registered_function_hasher>
> +  *non_overloaded_function_table;
> +
> /* RAII class for enabling enough RVV features to define the built-in
>     types and implement the riscv_vector.h pragma.
> @@ -3369,7 +3409,9 @@ function_builder::get_attributes (const function_instance &instance)
> registered_function &
> function_builder::add_function (const function_instance &instance,
> const char *name, tree fntype, tree attrs,
> - bool placeholder_p)
> + bool placeholder_p, const char *overload_name,
> + const vec<tree> &argument_types,
> + bool overloaded_p = false)
> {
>    unsigned int code = vec_safe_length (registered_functions);
>    code = (code << RISCV_BUILTIN_SHIFT) + RISCV_BUILTIN_VECTOR;
> @@ -3395,6 +3437,9 @@ function_builder::add_function (const function_instance &instance,
>    registered_function &rfn = *ggc_alloc<registered_function> ();
>    rfn.instance = instance;
>    rfn.decl = decl;
> +  rfn.overload_name = overload_name ? xstrdup (overload_name) : NULL;
> +  rfn.argument_types = argument_types;
> +  rfn.overloaded_p = overloaded_p;
>    vec_safe_push (registered_functions, &rfn);
>    return rfn;
> @@ -3415,6 +3460,10 @@ function_builder::add_unique_function (const function_instance &instance,
>    if (!check_required_extensions (instance))
>      return;
> +  /* Also add the function under its overloaded alias, if we want
> +     a separate decl for each instance of an overloaded function.  */
> +  char *overload_name = shape->get_name (*this, instance, true);
> +
>    /* Add the function under its full (unique) name.  */
>    char *name = shape->get_name (*this, instance, false);
>    tree fntype
> @@ -3422,7 +3471,8 @@ function_builder::add_unique_function (const function_instance &instance,
> argument_types.address ());
>    tree attrs = get_attributes (instance);
>    registered_function &rfn
> -    = add_function (instance, name, fntype, attrs, false);
> +    = add_function (instance, name, fntype, attrs, false, overload_name,
> +     argument_types.copy ());
>    /* Enter the function into the hash table.  */
>    hashval_t hash = instance.hash ();
> @@ -3431,19 +3481,45 @@ function_builder::add_unique_function (const function_instance &instance,
>    gcc_assert (!*rfn_slot);
>    *rfn_slot = &rfn;
> -  /* Also add the function under its overloaded alias, if we want
> -     a separate decl for each instance of an overloaded function.  */
> -  char *overload_name = shape->get_name (*this, instance, true);
>    if (overload_name)
>      {
>        /* Attribute lists shouldn't be shared.  */
>        tree attrs = get_attributes (instance);
>        bool placeholder_p = !m_direct_overloads;
> -      add_function (instance, overload_name, fntype, attrs, placeholder_p);
> +      add_function (instance, overload_name, fntype, attrs, placeholder_p, NULL,
> +     vNULL);
> +
> +      /* Enter the function into the non-overloaded hash table.  */
> +      hash = rfn.overloaded_hash ();
> +      rfn_slot = non_overloaded_function_table->find_slot_with_hash (&rfn, hash,
> +      INSERT);
> +      gcc_assert (!*rfn_slot);
> +      *rfn_slot = &rfn;
>      }
>    obstack_free (&m_string_obstack, name);
> }
> +/* Add overloaded function for gcc. */
> +void
> +function_builder::add_overloaded_function (const function_instance &instance,
> +    const function_shape *shape)
> +{
> +  if (!check_required_extensions (instance))
> +    return;
> +
> +  char *name = shape->get_name (*this, instance, true);
> +
> +  if (name)
> +    {
> +      /* To avoid API conflicting, take void return type and void argument
> + for the overloaded function.  */
> +      tree fntype = build_function_type (void_type_node, void_list_node);
> +      add_function (instance, name, fntype, NULL_TREE, m_direct_overloads, name,
> +     vNULL, true);
> +      obstack_free (&m_string_obstack, name);
> +    }
> +}
> +
> function_call_info::function_call_info (location_t location_in,
> const function_instance &instance_in,
> tree fndecl_in)
> @@ -3991,6 +4067,122 @@ 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)
> +{
> +  if (instance.base->may_require_vxrm_p ()
> +      || (instance.base->may_require_frm_p ()
> +   && (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
> +       == INTEGER_TYPE)))
> +    return true;
> +  return false;
> +}
> +
> +hashval_t
> +registered_function::overloaded_hash (const vec<tree, va_gc> &arglist)
> +{
> +  argument_types = vNULL;
> +  unsigned int len = arglist.length ();
> +
> +  for (unsigned int i = 0; i < len; i++)
> +    {
> +      /* vint8m1_t __riscv_vget_i8m1(vint8m2_t src, size_t index);
> +      When the user calls vget intrinsic, the __riscv_vget_i8m1(src, 1)
> +       form is used. The compiler recognizes that the parameter index is signed
> +       int, which is inconsistent with size_t, so the index is converted to
> +       size_t type in order to get correct hash value. vint8m2_t
> +       __riscv_vset(vint8m2_t dest, size_t index, vint8m1_t value); The reason
> +       is the same as above. */
> +      if ((instance.base == bases::vget && (i == (len - 1)))
> +   || (instance.base == bases::vset && (i == (len - 2))))
> + argument_types.safe_push (size_type_node);
> +      /* Vector fixed-point arithmetic instructions requiring argument vxrm.
> +      For example: vuint32m4_t __riscv_vaaddu(vuint32m4_t vs2,
> +      vuint32m4_t vs1, unsigned int vxrm, size_t vl); The user calls vaaddu
> +      intrinsic in the form of __riscv_vaaddu(vs2, vs1, 2, vl). The compiler
> +      recognizes that the parameter vxrm is a signed int, which is inconsistent
> +      with the parameter unsigned int vxrm declared by intrinsic, so the
> +      parameter vxrm is converted to an unsigned int type in order to get
> +      correct hash value.
> +
> +      Vector Floating-Point Instructions requiring argument frm.
> +      DEF_RVV_FUNCTION (vfadd, alu, full_preds, f_vvv_ops)
> +      DEF_RVV_FUNCTION (vfadd_frm, alu_frm, full_preds, f_vvv_ops)
> +      Taking vfadd as an example, theoretically we can add base or shape to the
> +      hash value to distinguish whether the frm parameter is required.
> +      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);
> +      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned int
> +      frm, size_t vl);
> +
> +     However, the current registration mechanism of overloaded intinsic for gcc
> +      limits the intrinsic obtained by entering the hook to always be vfadd, not
> +      vfadd_frm. Therefore, the correct hash value cannot be obtained through the
> +      parameter list and overload name, base or shape.
> +      +--------+---------------------------+-------------------+
> +      | index  | name                      | kind              |
> +      +--------+---------------------------+-------------------+
> +      | 124733 | __riscv_vfadd             | Overloaded        | <- Hook fun code
> +      +--------+---------------------------+-------------------+
> +      | 124735 |  __riscv_vfadd_vv_f32m1   | Non-overloaded    |
> +      +--------+---------------------------+-------------------+
> +      | 124737 | __riscv_vfadd             | Placeholder       |
> +      +--------+---------------------------+-------------------+
> +      | ...                                                    |
> +      +--------+---------------------------+-------------------+
> +      | ...                                                    |
> +      +--------+---------------------------+-------------------+
> +      | 125739 | __riscv_vfadd             | Overloaded        |
> +      +--------+---------------------------+-------------------+
> +      | 125741 | __riscv_vfadd_vv_f32m1_rm | Non-overloaded    |
> +      +--------+---------------------------+-------------------+
> +      | 125743 | __riscv_vfadd             | Placeholder       |
> +      +--------+---------------------------+-------------------+
> +
> +     Therefore, the hash value cannot be added with base or shape, and needs
> +      to be distinguished by whether the penultimate parameter is INTEGER_TYPE. */
> +      else if (has_vxrm_or_frm_p (instance, arglist) && (i == (len - 2)))
> + argument_types.safe_push (unsigned_type_node);
> +      else
> + argument_types.safe_push (TREE_TYPE (arglist[i]));
> +    }
> +  return overloaded_hash ();
> +}
> +
> +inline hashval_t
> +non_overloaded_registered_function_hasher::hash (value_type value)
> +{
> +  return value->overloaded_hash ();
> +}
> +
> +inline bool
> +non_overloaded_registered_function_hasher::equal (value_type value,
> +   const compare_type &key)
> +{
> +  return ((strcmp (value->overload_name, key->overload_name) == 0)
> +   && value->overloaded_hash () == key->overloaded_hash ());
> +}
> +
> /* If TYPE is a built-in type defined by the RVV ABI, return the mangled name,
>     otherwise return NULL.  */
> const char *
> @@ -4139,7 +4331,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 +4348,8 @@ handle_pragma_vector ()
>    /* Define the functions.  */
>    function_table = new hash_table<registered_function_hasher> (1023);
> +  non_overloaded_function_table
> +    = new hash_table<non_overloaded_registered_function_hasher> (1023);
>    function_builder builder;
>    for (unsigned int i = 0; i < ARRAY_SIZE (function_groups); ++i)
>      builder.register_function_group (function_groups[i]);
> @@ -4208,6 +4402,24 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
>    TREE_TYPE (rfn.decl), nargs, args).check ();
> }
> +tree
> +resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
> +{
> +  if (code >= vec_safe_length (registered_functions))
> +    return NULL_TREE;
> +
> +  registered_function *rfun = (*registered_functions)[code];
> +
> +  if (!rfun || !rfun->overloaded_p)
> +    return NULL_TREE;
> +
> +  hashval_t hash = rfun->overloaded_hash (*arglist);
> +  registered_function *rfn
> +    = non_overloaded_function_table->find_with_hash (rfun, hash);
> +  gcc_assert (rfn);
> +  return rfn->decl;
> +}
> +
> function_instance
> get_read_vl_instance (void)
> {
> diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
> index e358a8e4d91..cd8ccab1724 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.  */
> @@ -417,6 +420,12 @@ public:
>    /* Return true if intrinsics has rounding mode operand.  */
>    virtual bool has_rounding_mode_operand_p () const;
> +  /* Return true if intrinsics maybe require vxrm operand.  */
> +  virtual bool may_require_vxrm_p () const;
> +
> +  /* Return true if intrinsics maybe require frm operand.  */
> +  virtual bool may_require_frm_p () const;
> +
>    /* Try to fold the given gimple call.  Return the new gimple statement
>       on success, otherwise return null.  */
>    virtual gimple *fold (gimple_folder &) const { return NULL; }
> @@ -674,6 +683,22 @@ function_base::has_rounding_mode_operand_p () const
>    return false;
> }
> +/* We choose to return false by default since most of the intrinsics does
> +   not need frm operand.  */
> +inline bool
> +function_base::may_require_frm_p () const
> +{
> +  return false;
> +}
> +
> +/* We choose to return false by default since most of the intrinsics does
> +   not need vxrm operand.  */
> +inline bool
> +function_base::may_require_vxrm_p () const
> +{
> +  return false;
> +}
> +
> /* Since most of intrinsics can be overloaded, we set it true by default.  */
> inline bool
> function_base::can_be_overloaded_p (enum predication_type_index) const
> 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
>  
>  

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
  2023-10-31 11:36   ` Li Xu
  2023-10-31 12:35     ` Li, Pan2
  2023-11-01  0:26     ` juzhe.zhong
@ 2023-11-06  1:26     ` juzhe.zhong
  2023-11-06  2:31       ` Li Xu
  2 siblings, 1 reply; 7+ messages in thread
From: juzhe.zhong @ 2023-11-06  1:26 UTC (permalink / raw)
  To: Li Xu; +Cc: gcc-patches, kito.cheng, palmer

[-- Attachment #1: Type: text/plain, Size: 60814 bytes --]

Hi, LiXu. Seems no objection. You can commit it.
Thanks for supporting it.



juzhe.zhong@rivai.ai
 
From: Li Xu
Date: 2023-10-31 19:36
To: juzhe.zhong@rivai.ai
CC: gcc-patches; kito.cheng; palmer
Subject: Re: Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
All overload and non-overload intrinsics have been tested successfully on gcc and g++.
 
Thanks.
 
 
> -----原始邮件-----发件人:"juzhe.zhong@rivai.ai" <juzhe.zhong@rivai.ai>发送时间:2023-10-31 17:07:11 (星期二)收件人:"Li Xu" <xuli1@eswincomputing.com>, gcc-patches <gcc-patches@gcc.gnu.org>抄送:"kito.cheng" <kito.cheng@gmail.com>, palmer <palmer@dabbelt.com>, "Li Xu" <xuli1@eswincomputing.com>主题:Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
> 
> LGTM from my side.
> 
> Give kito one more day to review it.
> 
> Thanks for support this feature !
> 
> juzhe.zhong@rivai.ai
>  
> From: Li Xu
> Date: 2023-10-31 17:03
> To: gcc-patches
> CC: kito.cheng; palmer; juzhe.zhong; xuli
> Subject: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
> From: xuli <xuli1@eswincomputing.com>
>  
> Update in v6:
> * Rename maybe_require_frm_p to may_require_frm_p.
> * Rename maybe_require_vxrm_p to may_require_vxrm_p.
> * Move may_require_frm_p and may_require_vxrm_p to function_base.
>  
> Update in v5:
> * Split has_vxrm_or_frm_p into maybe_require_frm_p and
>   maybe_require_vxrm_p.
> * Adjust comments.
>  
> Update in v4:
> * Remove class function_resolver.
> * Remove function get_non_overloaded_instance.
> * Add overloaded hash traits for non-overloaded intrinsic.
> * All overloaded intrinsics are implemented, and the tests pass.
>  
> Update in v3:
>  
> * Rewrite comment for overloaded function add.
> * Move get_non_overloaded_instance to function_base.
>  
> Update in v2:
>  
> * Add get_non_overloaded_instance for function instance.
> * Fix overload check for policy function.
> * Enrich the test cases check.
>  
> Original log:
>  
> This patch would like add the framework to support the RVV overloaded
> intrinsic API in riscv-xxx-xxx-gcc, like riscv-xxx-xxx-g++ did.
>  
> However, it almost leverage the hook TARGET_RESOLVE_OVERLOADED_BUILTIN
> with below steps.
>  
> * Register overloaded functions.
> * Add function_resolver for overloaded function resolving.
> * Add resolve API for function shape with default implementation.
> * Implement HOOK for navigating the overloaded API to non-overloaded API.
>  
> gcc/ChangeLog:
>  
>         * config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): New function for the hook.
>         (riscv_register_pragmas): Register the hook.
>         * config/riscv/riscv-protos.h (resolve_overloaded_builtin): New decl.
>         * config/riscv/riscv-vector-builtins-bases.cc: New function impl.
>         * 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 (function_base::may_require_frm_p): Ditto.
>         (function_base::may_require_vxrm_p): Ditto.
>  
> 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-bases.cc      |  69 +++++-
> .../riscv/riscv-vector-builtins-shapes.cc     |   1 +
> gcc/config/riscv/riscv-vector-builtins.cc     | 226 +++++++++++++++++-
> gcc/config/riscv/riscv-vector-builtins.h      |  27 ++-
> .../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 +++
> 24 files changed, 708 insertions(+), 18 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 = &empty;
> +
> +  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-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> index 0b1409a52e0..9bc2be2a6da 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> @@ -262,7 +262,8 @@ public:
>     vremu/vsadd/vsaddu/vssub/vssubu
>     vfadd/vfsub/
> */
> -template<rtx_code CODE, enum frm_op_type FRM_OP = NO_FRM>
> +template <rtx_code CODE, bool MAY_REQUIRE_FRM = false,
> +   enum frm_op_type FRM_OP = NO_FRM>
> class binop : public function_base
> {
> public:
> @@ -271,6 +272,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return MAY_REQUIRE_FRM; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -308,6 +311,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
> @@ -397,6 +402,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -630,6 +637,8 @@ class sat_op : public function_base
> public:
>    bool has_rounding_mode_operand_p () const override { return true; }
> +  bool may_require_vxrm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -652,6 +661,8 @@ class vnclip : public function_base
> public:
>    bool has_rounding_mode_operand_p () const override { return true; }
> +  bool may_require_vxrm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -1024,6 +1035,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1040,6 +1053,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1064,6 +1079,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1087,6 +1104,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1111,6 +1130,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1134,6 +1155,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1157,6 +1180,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1181,6 +1206,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1204,6 +1231,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1228,6 +1257,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1251,6 +1282,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1274,6 +1307,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1297,6 +1332,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1321,6 +1358,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_vf)
> @@ -1392,6 +1431,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (code_for_pred_fcvt_x_f (UNSPEC, e.arg_mode (0)));
> @@ -1418,6 +1459,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_x_v)
> @@ -1439,6 +1482,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1483,6 +1528,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1510,6 +1557,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_f_w)
> @@ -1555,6 +1604,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool apply_mask_policy_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -2164,20 +2215,20 @@ static CONSTEXPR const mask_misc<UNSPEC_VMSIF> vmsif_obj;
> static CONSTEXPR const mask_misc<UNSPEC_VMSOF> vmsof_obj;
> static CONSTEXPR const viota viota_obj;
> static CONSTEXPR const vid vid_obj;
> -static CONSTEXPR const binop<PLUS> vfadd_obj;
> -static CONSTEXPR const binop<MINUS> vfsub_obj;
> -static CONSTEXPR const binop<PLUS, HAS_FRM> vfadd_frm_obj;
> -static CONSTEXPR const binop<MINUS, HAS_FRM> vfsub_frm_obj;
> +static CONSTEXPR const binop<PLUS, true> vfadd_obj;
> +static CONSTEXPR const binop<MINUS, true> vfsub_obj;
> +static CONSTEXPR const binop<PLUS, true, HAS_FRM> vfadd_frm_obj;
> +static CONSTEXPR const binop<MINUS, true, HAS_FRM> vfsub_frm_obj;
> static CONSTEXPR const reverse_binop<MINUS> vfrsub_obj;
> static CONSTEXPR const reverse_binop<MINUS, HAS_FRM> vfrsub_frm_obj;
> static CONSTEXPR const widen_binop_fp<PLUS> vfwadd_obj;
> static CONSTEXPR const widen_binop_fp<PLUS, HAS_FRM> vfwadd_frm_obj;
> static CONSTEXPR const widen_binop_fp<MINUS> vfwsub_obj;
> static CONSTEXPR const widen_binop_fp<MINUS, HAS_FRM> vfwsub_frm_obj;
> -static CONSTEXPR const binop<MULT> vfmul_obj;
> -static CONSTEXPR const binop<MULT, HAS_FRM> vfmul_frm_obj;
> -static CONSTEXPR const binop<DIV> vfdiv_obj;
> -static CONSTEXPR const binop<DIV, HAS_FRM> vfdiv_frm_obj;
> +static CONSTEXPR const binop<MULT, true> vfmul_obj;
> +static CONSTEXPR const binop<MULT,  true, HAS_FRM> vfmul_frm_obj;
> +static CONSTEXPR const binop<DIV, true> vfdiv_obj;
> +static CONSTEXPR const binop<DIV,  true, HAS_FRM> vfdiv_frm_obj;
> static CONSTEXPR const reverse_binop<DIV> vfrdiv_obj;
> static CONSTEXPR const reverse_binop<DIV, HAS_FRM> vfrdiv_frm_obj;
> static CONSTEXPR const widen_binop_fp<MULT> vfwmul_obj;
> 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..e7564b9cf7c 100644
> --- a/gcc/config/riscv/riscv-vector-builtins.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins.cc
> @@ -80,6 +80,32 @@ public:
>    /* The decl itself.  */
>    tree GTY ((skip)) decl;
> +
> +  /* The overload hash of non-overloaded intrinsic is determined by
> +     the overload name and argument list. Adding the overload name to
> +     the hash is also to address the following situations:
> +     vint16mf4_t  __riscv_vreinterpret_i16mf4 (vfloat16mf4_t src);
> +     vuint16mf4_t __riscv_vreinterpret_u16mf4 (vfloat16mf4_t src);
> +     The base, shape and argument list of the vreinterpret instance are
> +     the same, only the overload name is different. Therefore, it is
> +     enough to add overload_name and argument list to the hash value.*/
> +  const char *overload_name;
> +
> +  /* The argument list part of the hash value. Add the unsigned/signed type
> +     and machine mode of each argument to the hash value. */
> +  vec<tree> GTY ((skip)) argument_types;
> +
> +  /* True if the decl represents an overloaded function that needs to be
> +     resolved. */
> +  bool overloaded_p;
> +
> +  /* The hash value to indicate the non-overloaded function. Generate hash value
> +     based on overload_name and argument_types. */
> +  hashval_t overloaded_hash () const;
> +
> +  /* Generate hash value based on the overload_name and the argument list passed
> +     by the user when calling. */
> +  hashval_t overloaded_hash (const vec<tree, va_gc> &);
> };
> /* Hash traits for registered_function.  */
> @@ -91,6 +117,14 @@ struct registered_function_hasher : nofree_ptr_hash<registered_function>
>    static bool equal (value_type, const compare_type &);
> };
> +/* Hash traits for overload registered_function. */
> +struct non_overloaded_registered_function_hasher
> +  : nofree_ptr_hash<registered_function>
> +{
> +  static hashval_t hash (value_type);
> +  static bool equal (value_type, const compare_type &);
> +};
> +
> /* Static information about each RVV type.  */
> static CONSTEXPR const vector_type_info vector_types[] = {
> #define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, ARGS...)                          \
> @@ -2611,6 +2645,12 @@ static GTY (()) vec<registered_function *, va_gc> *registered_functions;
>     overloaded functions.  */
> static hash_table<registered_function_hasher> *function_table;
> +/* All registered function decls, hashed on overload_name and argument list
> +   of the registered_function.  This is used for looking up implementations
> +   of non-overloaded functions. */
> +static hash_table<non_overloaded_registered_function_hasher>
> +  *non_overloaded_function_table;
> +
> /* RAII class for enabling enough RVV features to define the built-in
>     types and implement the riscv_vector.h pragma.
> @@ -3369,7 +3409,9 @@ function_builder::get_attributes (const function_instance &instance)
> registered_function &
> function_builder::add_function (const function_instance &instance,
> const char *name, tree fntype, tree attrs,
> - bool placeholder_p)
> + bool placeholder_p, const char *overload_name,
> + const vec<tree> &argument_types,
> + bool overloaded_p = false)
> {
>    unsigned int code = vec_safe_length (registered_functions);
>    code = (code << RISCV_BUILTIN_SHIFT) + RISCV_BUILTIN_VECTOR;
> @@ -3395,6 +3437,9 @@ function_builder::add_function (const function_instance &instance,
>    registered_function &rfn = *ggc_alloc<registered_function> ();
>    rfn.instance = instance;
>    rfn.decl = decl;
> +  rfn.overload_name = overload_name ? xstrdup (overload_name) : NULL;
> +  rfn.argument_types = argument_types;
> +  rfn.overloaded_p = overloaded_p;
>    vec_safe_push (registered_functions, &rfn);
>    return rfn;
> @@ -3415,6 +3460,10 @@ function_builder::add_unique_function (const function_instance &instance,
>    if (!check_required_extensions (instance))
>      return;
> +  /* Also add the function under its overloaded alias, if we want
> +     a separate decl for each instance of an overloaded function.  */
> +  char *overload_name = shape->get_name (*this, instance, true);
> +
>    /* Add the function under its full (unique) name.  */
>    char *name = shape->get_name (*this, instance, false);
>    tree fntype
> @@ -3422,7 +3471,8 @@ function_builder::add_unique_function (const function_instance &instance,
> argument_types.address ());
>    tree attrs = get_attributes (instance);
>    registered_function &rfn
> -    = add_function (instance, name, fntype, attrs, false);
> +    = add_function (instance, name, fntype, attrs, false, overload_name,
> +     argument_types.copy ());
>    /* Enter the function into the hash table.  */
>    hashval_t hash = instance.hash ();
> @@ -3431,19 +3481,45 @@ function_builder::add_unique_function (const function_instance &instance,
>    gcc_assert (!*rfn_slot);
>    *rfn_slot = &rfn;
> -  /* Also add the function under its overloaded alias, if we want
> -     a separate decl for each instance of an overloaded function.  */
> -  char *overload_name = shape->get_name (*this, instance, true);
>    if (overload_name)
>      {
>        /* Attribute lists shouldn't be shared.  */
>        tree attrs = get_attributes (instance);
>        bool placeholder_p = !m_direct_overloads;
> -      add_function (instance, overload_name, fntype, attrs, placeholder_p);
> +      add_function (instance, overload_name, fntype, attrs, placeholder_p, NULL,
> +     vNULL);
> +
> +      /* Enter the function into the non-overloaded hash table.  */
> +      hash = rfn.overloaded_hash ();
> +      rfn_slot = non_overloaded_function_table->find_slot_with_hash (&rfn, hash,
> +      INSERT);
> +      gcc_assert (!*rfn_slot);
> +      *rfn_slot = &rfn;
>      }
>    obstack_free (&m_string_obstack, name);
> }
> +/* Add overloaded function for gcc. */
> +void
> +function_builder::add_overloaded_function (const function_instance &instance,
> +    const function_shape *shape)
> +{
> +  if (!check_required_extensions (instance))
> +    return;
> +
> +  char *name = shape->get_name (*this, instance, true);
> +
> +  if (name)
> +    {
> +      /* To avoid API conflicting, take void return type and void argument
> + for the overloaded function.  */
> +      tree fntype = build_function_type (void_type_node, void_list_node);
> +      add_function (instance, name, fntype, NULL_TREE, m_direct_overloads, name,
> +     vNULL, true);
> +      obstack_free (&m_string_obstack, name);
> +    }
> +}
> +
> function_call_info::function_call_info (location_t location_in,
> const function_instance &instance_in,
> tree fndecl_in)
> @@ -3991,6 +4067,122 @@ 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)
> +{
> +  if (instance.base->may_require_vxrm_p ()
> +      || (instance.base->may_require_frm_p ()
> +   && (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
> +       == INTEGER_TYPE)))
> +    return true;
> +  return false;
> +}
> +
> +hashval_t
> +registered_function::overloaded_hash (const vec<tree, va_gc> &arglist)
> +{
> +  argument_types = vNULL;
> +  unsigned int len = arglist.length ();
> +
> +  for (unsigned int i = 0; i < len; i++)
> +    {
> +      /* vint8m1_t __riscv_vget_i8m1(vint8m2_t src, size_t index);
> +      When the user calls vget intrinsic, the __riscv_vget_i8m1(src, 1)
> +       form is used. The compiler recognizes that the parameter index is signed
> +       int, which is inconsistent with size_t, so the index is converted to
> +       size_t type in order to get correct hash value. vint8m2_t
> +       __riscv_vset(vint8m2_t dest, size_t index, vint8m1_t value); The reason
> +       is the same as above. */
> +      if ((instance.base == bases::vget && (i == (len - 1)))
> +   || (instance.base == bases::vset && (i == (len - 2))))
> + argument_types.safe_push (size_type_node);
> +      /* Vector fixed-point arithmetic instructions requiring argument vxrm.
> +      For example: vuint32m4_t __riscv_vaaddu(vuint32m4_t vs2,
> +      vuint32m4_t vs1, unsigned int vxrm, size_t vl); The user calls vaaddu
> +      intrinsic in the form of __riscv_vaaddu(vs2, vs1, 2, vl). The compiler
> +      recognizes that the parameter vxrm is a signed int, which is inconsistent
> +      with the parameter unsigned int vxrm declared by intrinsic, so the
> +      parameter vxrm is converted to an unsigned int type in order to get
> +      correct hash value.
> +
> +      Vector Floating-Point Instructions requiring argument frm.
> +      DEF_RVV_FUNCTION (vfadd, alu, full_preds, f_vvv_ops)
> +      DEF_RVV_FUNCTION (vfadd_frm, alu_frm, full_preds, f_vvv_ops)
> +      Taking vfadd as an example, theoretically we can add base or shape to the
> +      hash value to distinguish whether the frm parameter is required.
> +      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);
> +      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned int
> +      frm, size_t vl);
> +
> +     However, the current registration mechanism of overloaded intinsic for gcc
> +      limits the intrinsic obtained by entering the hook to always be vfadd, not
> +      vfadd_frm. Therefore, the correct hash value cannot be obtained through the
> +      parameter list and overload name, base or shape.
> +      +--------+---------------------------+-------------------+
> +      | index  | name                      | kind              |
> +      +--------+---------------------------+-------------------+
> +      | 124733 | __riscv_vfadd             | Overloaded        | <- Hook fun code
> +      +--------+---------------------------+-------------------+
> +      | 124735 |  __riscv_vfadd_vv_f32m1   | Non-overloaded    |
> +      +--------+---------------------------+-------------------+
> +      | 124737 | __riscv_vfadd             | Placeholder       |
> +      +--------+---------------------------+-------------------+
> +      | ...                                                    |
> +      +--------+---------------------------+-------------------+
> +      | ...                                                    |
> +      +--------+---------------------------+-------------------+
> +      | 125739 | __riscv_vfadd             | Overloaded        |
> +      +--------+---------------------------+-------------------+
> +      | 125741 | __riscv_vfadd_vv_f32m1_rm | Non-overloaded    |
> +      +--------+---------------------------+-------------------+
> +      | 125743 | __riscv_vfadd             | Placeholder       |
> +      +--------+---------------------------+-------------------+
> +
> +     Therefore, the hash value cannot be added with base or shape, and needs
> +      to be distinguished by whether the penultimate parameter is INTEGER_TYPE. */
> +      else if (has_vxrm_or_frm_p (instance, arglist) && (i == (len - 2)))
> + argument_types.safe_push (unsigned_type_node);
> +      else
> + argument_types.safe_push (TREE_TYPE (arglist[i]));
> +    }
> +  return overloaded_hash ();
> +}
> +
> +inline hashval_t
> +non_overloaded_registered_function_hasher::hash (value_type value)
> +{
> +  return value->overloaded_hash ();
> +}
> +
> +inline bool
> +non_overloaded_registered_function_hasher::equal (value_type value,
> +   const compare_type &key)
> +{
> +  return ((strcmp (value->overload_name, key->overload_name) == 0)
> +   && value->overloaded_hash () == key->overloaded_hash ());
> +}
> +
> /* If TYPE is a built-in type defined by the RVV ABI, return the mangled name,
>     otherwise return NULL.  */
> const char *
> @@ -4139,7 +4331,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 +4348,8 @@ handle_pragma_vector ()
>    /* Define the functions.  */
>    function_table = new hash_table<registered_function_hasher> (1023);
> +  non_overloaded_function_table
> +    = new hash_table<non_overloaded_registered_function_hasher> (1023);
>    function_builder builder;
>    for (unsigned int i = 0; i < ARRAY_SIZE (function_groups); ++i)
>      builder.register_function_group (function_groups[i]);
> @@ -4208,6 +4402,24 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
>    TREE_TYPE (rfn.decl), nargs, args).check ();
> }
> +tree
> +resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
> +{
> +  if (code >= vec_safe_length (registered_functions))
> +    return NULL_TREE;
> +
> +  registered_function *rfun = (*registered_functions)[code];
> +
> +  if (!rfun || !rfun->overloaded_p)
> +    return NULL_TREE;
> +
> +  hashval_t hash = rfun->overloaded_hash (*arglist);
> +  registered_function *rfn
> +    = non_overloaded_function_table->find_with_hash (rfun, hash);
> +  gcc_assert (rfn);
> +  return rfn->decl;
> +}
> +
> function_instance
> get_read_vl_instance (void)
> {
> diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
> index e358a8e4d91..cd8ccab1724 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.  */
> @@ -417,6 +420,12 @@ public:
>    /* Return true if intrinsics has rounding mode operand.  */
>    virtual bool has_rounding_mode_operand_p () const;
> +  /* Return true if intrinsics maybe require vxrm operand.  */
> +  virtual bool may_require_vxrm_p () const;
> +
> +  /* Return true if intrinsics maybe require frm operand.  */
> +  virtual bool may_require_frm_p () const;
> +
>    /* Try to fold the given gimple call.  Return the new gimple statement
>       on success, otherwise return null.  */
>    virtual gimple *fold (gimple_folder &) const { return NULL; }
> @@ -674,6 +683,22 @@ function_base::has_rounding_mode_operand_p () const
>    return false;
> }
> +/* We choose to return false by default since most of the intrinsics does
> +   not need frm operand.  */
> +inline bool
> +function_base::may_require_frm_p () const
> +{
> +  return false;
> +}
> +
> +/* We choose to return false by default since most of the intrinsics does
> +   not need vxrm operand.  */
> +inline bool
> +function_base::may_require_vxrm_p () const
> +{
> +  return false;
> +}
> +
> /* Since most of intrinsics can be overloaded, we set it true by default.  */
> inline bool
> function_base::can_be_overloaded_p (enum predication_type_index) const
> 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
>  
>  

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
  2023-11-06  1:26     ` juzhe.zhong
@ 2023-11-06  2:31       ` Li Xu
  0 siblings, 0 replies; 7+ messages in thread
From: Li Xu @ 2023-11-06  2:31 UTC (permalink / raw)
  To: juzhe.zhong; +Cc: gcc-patches, kito.cheng, palmer

[-- Attachment #1: Type: text/plain, Size: 61046 bytes --]

Committed, thanks juzhe.



xuli1@eswincomputing.com
 
From: juzhe.zhong@rivai.ai
Date: 2023-11-06 09:26
To: Li Xu
CC: gcc-patches; kito.cheng; palmer
Subject: Re: Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
Hi, LiXu. Seems no objection. You can commit it.
Thanks for supporting it.



juzhe.zhong@rivai.ai
 
From: Li Xu
Date: 2023-10-31 19:36
To: juzhe.zhong@rivai.ai
CC: gcc-patches; kito.cheng; palmer
Subject: Re: Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
All overload and non-overload intrinsics have been tested successfully on gcc and g++.
 
Thanks.
 
 
> -----原始邮件-----发件人:"juzhe.zhong@rivai.ai" <juzhe.zhong@rivai.ai>发送时间:2023-10-31 17:07:11 (星期二)收件人:"Li Xu" <xuli1@eswincomputing.com>, gcc-patches <gcc-patches@gcc.gnu.org>抄送:"kito.cheng" <kito.cheng@gmail.com>, palmer <palmer@dabbelt.com>, "Li Xu" <xuli1@eswincomputing.com>主题:Re: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
> 
> LGTM from my side.
> 
> Give kito one more day to review it.
> 
> Thanks for support this feature !
> 
> juzhe.zhong@rivai.ai
>  
> From: Li Xu
> Date: 2023-10-31 17:03
> To: gcc-patches
> CC: kito.cheng; palmer; juzhe.zhong; xuli
> Subject: [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic
> From: xuli <xuli1@eswincomputing.com>
>  
> Update in v6:
> * Rename maybe_require_frm_p to may_require_frm_p.
> * Rename maybe_require_vxrm_p to may_require_vxrm_p.
> * Move may_require_frm_p and may_require_vxrm_p to function_base.
>  
> Update in v5:
> * Split has_vxrm_or_frm_p into maybe_require_frm_p and
>   maybe_require_vxrm_p.
> * Adjust comments.
>  
> Update in v4:
> * Remove class function_resolver.
> * Remove function get_non_overloaded_instance.
> * Add overloaded hash traits for non-overloaded intrinsic.
> * All overloaded intrinsics are implemented, and the tests pass.
>  
> Update in v3:
>  
> * Rewrite comment for overloaded function add.
> * Move get_non_overloaded_instance to function_base.
>  
> Update in v2:
>  
> * Add get_non_overloaded_instance for function instance.
> * Fix overload check for policy function.
> * Enrich the test cases check.
>  
> Original log:
>  
> This patch would like add the framework to support the RVV overloaded
> intrinsic API in riscv-xxx-xxx-gcc, like riscv-xxx-xxx-g++ did.
>  
> However, it almost leverage the hook TARGET_RESOLVE_OVERLOADED_BUILTIN
> with below steps.
>  
> * Register overloaded functions.
> * Add function_resolver for overloaded function resolving.
> * Add resolve API for function shape with default implementation.
> * Implement HOOK for navigating the overloaded API to non-overloaded API.
>  
> gcc/ChangeLog:
>  
>         * config/riscv/riscv-c.cc (riscv_resolve_overloaded_builtin): New function for the hook.
>         (riscv_register_pragmas): Register the hook.
>         * config/riscv/riscv-protos.h (resolve_overloaded_builtin): New decl.
>         * config/riscv/riscv-vector-builtins-bases.cc: New function impl.
>         * 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 (function_base::may_require_frm_p): Ditto.
>         (function_base::may_require_vxrm_p): Ditto.
>  
> 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-bases.cc      |  69 +++++-
> .../riscv/riscv-vector-builtins-shapes.cc     |   1 +
> gcc/config/riscv/riscv-vector-builtins.cc     | 226 +++++++++++++++++-
> gcc/config/riscv/riscv-vector-builtins.h      |  27 ++-
> .../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 +++
> 24 files changed, 708 insertions(+), 18 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 = &empty;
> +
> +  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-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> index 0b1409a52e0..9bc2be2a6da 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> @@ -262,7 +262,8 @@ public:
>     vremu/vsadd/vsaddu/vssub/vssubu
>     vfadd/vfsub/
> */
> -template<rtx_code CODE, enum frm_op_type FRM_OP = NO_FRM>
> +template <rtx_code CODE, bool MAY_REQUIRE_FRM = false,
> +   enum frm_op_type FRM_OP = NO_FRM>
> class binop : public function_base
> {
> public:
> @@ -271,6 +272,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return MAY_REQUIRE_FRM; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -308,6 +311,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
> @@ -397,6 +402,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -630,6 +637,8 @@ class sat_op : public function_base
> public:
>    bool has_rounding_mode_operand_p () const override { return true; }
> +  bool may_require_vxrm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -652,6 +661,8 @@ class vnclip : public function_base
> public:
>    bool has_rounding_mode_operand_p () const override { return true; }
> +  bool may_require_vxrm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      switch (e.op_info->op)
> @@ -1024,6 +1035,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1040,6 +1053,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1064,6 +1079,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1087,6 +1104,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1111,6 +1130,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1134,6 +1155,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1157,6 +1180,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1181,6 +1206,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1204,6 +1231,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1228,6 +1257,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1251,6 +1282,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1274,6 +1307,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1297,6 +1332,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool has_merge_operand_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -1321,6 +1358,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_vf)
> @@ -1392,6 +1431,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (code_for_pred_fcvt_x_f (UNSPEC, e.arg_mode (0)));
> @@ -1418,6 +1459,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_x_v)
> @@ -1439,6 +1482,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1483,6 +1528,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      return e.use_exact_insn (
> @@ -1510,6 +1557,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    rtx expand (function_expander &e) const override
>    {
>      if (e.op_info->op == OP_TYPE_f_w)
> @@ -1555,6 +1604,8 @@ public:
>      return FRM_OP == HAS_FRM;
>    }
> +  bool may_require_frm_p () const override { return true; }
> +
>    bool apply_mask_policy_p () const override { return false; }
>    rtx expand (function_expander &e) const override
> @@ -2164,20 +2215,20 @@ static CONSTEXPR const mask_misc<UNSPEC_VMSIF> vmsif_obj;
> static CONSTEXPR const mask_misc<UNSPEC_VMSOF> vmsof_obj;
> static CONSTEXPR const viota viota_obj;
> static CONSTEXPR const vid vid_obj;
> -static CONSTEXPR const binop<PLUS> vfadd_obj;
> -static CONSTEXPR const binop<MINUS> vfsub_obj;
> -static CONSTEXPR const binop<PLUS, HAS_FRM> vfadd_frm_obj;
> -static CONSTEXPR const binop<MINUS, HAS_FRM> vfsub_frm_obj;
> +static CONSTEXPR const binop<PLUS, true> vfadd_obj;
> +static CONSTEXPR const binop<MINUS, true> vfsub_obj;
> +static CONSTEXPR const binop<PLUS, true, HAS_FRM> vfadd_frm_obj;
> +static CONSTEXPR const binop<MINUS, true, HAS_FRM> vfsub_frm_obj;
> static CONSTEXPR const reverse_binop<MINUS> vfrsub_obj;
> static CONSTEXPR const reverse_binop<MINUS, HAS_FRM> vfrsub_frm_obj;
> static CONSTEXPR const widen_binop_fp<PLUS> vfwadd_obj;
> static CONSTEXPR const widen_binop_fp<PLUS, HAS_FRM> vfwadd_frm_obj;
> static CONSTEXPR const widen_binop_fp<MINUS> vfwsub_obj;
> static CONSTEXPR const widen_binop_fp<MINUS, HAS_FRM> vfwsub_frm_obj;
> -static CONSTEXPR const binop<MULT> vfmul_obj;
> -static CONSTEXPR const binop<MULT, HAS_FRM> vfmul_frm_obj;
> -static CONSTEXPR const binop<DIV> vfdiv_obj;
> -static CONSTEXPR const binop<DIV, HAS_FRM> vfdiv_frm_obj;
> +static CONSTEXPR const binop<MULT, true> vfmul_obj;
> +static CONSTEXPR const binop<MULT,  true, HAS_FRM> vfmul_frm_obj;
> +static CONSTEXPR const binop<DIV, true> vfdiv_obj;
> +static CONSTEXPR const binop<DIV,  true, HAS_FRM> vfdiv_frm_obj;
> static CONSTEXPR const reverse_binop<DIV> vfrdiv_obj;
> static CONSTEXPR const reverse_binop<DIV, HAS_FRM> vfrdiv_frm_obj;
> static CONSTEXPR const widen_binop_fp<MULT> vfwmul_obj;
> 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..e7564b9cf7c 100644
> --- a/gcc/config/riscv/riscv-vector-builtins.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins.cc
> @@ -80,6 +80,32 @@ public:
>    /* The decl itself.  */
>    tree GTY ((skip)) decl;
> +
> +  /* The overload hash of non-overloaded intrinsic is determined by
> +     the overload name and argument list. Adding the overload name to
> +     the hash is also to address the following situations:
> +     vint16mf4_t  __riscv_vreinterpret_i16mf4 (vfloat16mf4_t src);
> +     vuint16mf4_t __riscv_vreinterpret_u16mf4 (vfloat16mf4_t src);
> +     The base, shape and argument list of the vreinterpret instance are
> +     the same, only the overload name is different. Therefore, it is
> +     enough to add overload_name and argument list to the hash value.*/
> +  const char *overload_name;
> +
> +  /* The argument list part of the hash value. Add the unsigned/signed type
> +     and machine mode of each argument to the hash value. */
> +  vec<tree> GTY ((skip)) argument_types;
> +
> +  /* True if the decl represents an overloaded function that needs to be
> +     resolved. */
> +  bool overloaded_p;
> +
> +  /* The hash value to indicate the non-overloaded function. Generate hash value
> +     based on overload_name and argument_types. */
> +  hashval_t overloaded_hash () const;
> +
> +  /* Generate hash value based on the overload_name and the argument list passed
> +     by the user when calling. */
> +  hashval_t overloaded_hash (const vec<tree, va_gc> &);
> };
> /* Hash traits for registered_function.  */
> @@ -91,6 +117,14 @@ struct registered_function_hasher : nofree_ptr_hash<registered_function>
>    static bool equal (value_type, const compare_type &);
> };
> +/* Hash traits for overload registered_function. */
> +struct non_overloaded_registered_function_hasher
> +  : nofree_ptr_hash<registered_function>
> +{
> +  static hashval_t hash (value_type);
> +  static bool equal (value_type, const compare_type &);
> +};
> +
> /* Static information about each RVV type.  */
> static CONSTEXPR const vector_type_info vector_types[] = {
> #define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, ARGS...)                          \
> @@ -2611,6 +2645,12 @@ static GTY (()) vec<registered_function *, va_gc> *registered_functions;
>     overloaded functions.  */
> static hash_table<registered_function_hasher> *function_table;
> +/* All registered function decls, hashed on overload_name and argument list
> +   of the registered_function.  This is used for looking up implementations
> +   of non-overloaded functions. */
> +static hash_table<non_overloaded_registered_function_hasher>
> +  *non_overloaded_function_table;
> +
> /* RAII class for enabling enough RVV features to define the built-in
>     types and implement the riscv_vector.h pragma.
> @@ -3369,7 +3409,9 @@ function_builder::get_attributes (const function_instance &instance)
> registered_function &
> function_builder::add_function (const function_instance &instance,
> const char *name, tree fntype, tree attrs,
> - bool placeholder_p)
> + bool placeholder_p, const char *overload_name,
> + const vec<tree> &argument_types,
> + bool overloaded_p = false)
> {
>    unsigned int code = vec_safe_length (registered_functions);
>    code = (code << RISCV_BUILTIN_SHIFT) + RISCV_BUILTIN_VECTOR;
> @@ -3395,6 +3437,9 @@ function_builder::add_function (const function_instance &instance,
>    registered_function &rfn = *ggc_alloc<registered_function> ();
>    rfn.instance = instance;
>    rfn.decl = decl;
> +  rfn.overload_name = overload_name ? xstrdup (overload_name) : NULL;
> +  rfn.argument_types = argument_types;
> +  rfn.overloaded_p = overloaded_p;
>    vec_safe_push (registered_functions, &rfn);
>    return rfn;
> @@ -3415,6 +3460,10 @@ function_builder::add_unique_function (const function_instance &instance,
>    if (!check_required_extensions (instance))
>      return;
> +  /* Also add the function under its overloaded alias, if we want
> +     a separate decl for each instance of an overloaded function.  */
> +  char *overload_name = shape->get_name (*this, instance, true);
> +
>    /* Add the function under its full (unique) name.  */
>    char *name = shape->get_name (*this, instance, false);
>    tree fntype
> @@ -3422,7 +3471,8 @@ function_builder::add_unique_function (const function_instance &instance,
> argument_types.address ());
>    tree attrs = get_attributes (instance);
>    registered_function &rfn
> -    = add_function (instance, name, fntype, attrs, false);
> +    = add_function (instance, name, fntype, attrs, false, overload_name,
> +     argument_types.copy ());
>    /* Enter the function into the hash table.  */
>    hashval_t hash = instance.hash ();
> @@ -3431,19 +3481,45 @@ function_builder::add_unique_function (const function_instance &instance,
>    gcc_assert (!*rfn_slot);
>    *rfn_slot = &rfn;
> -  /* Also add the function under its overloaded alias, if we want
> -     a separate decl for each instance of an overloaded function.  */
> -  char *overload_name = shape->get_name (*this, instance, true);
>    if (overload_name)
>      {
>        /* Attribute lists shouldn't be shared.  */
>        tree attrs = get_attributes (instance);
>        bool placeholder_p = !m_direct_overloads;
> -      add_function (instance, overload_name, fntype, attrs, placeholder_p);
> +      add_function (instance, overload_name, fntype, attrs, placeholder_p, NULL,
> +     vNULL);
> +
> +      /* Enter the function into the non-overloaded hash table.  */
> +      hash = rfn.overloaded_hash ();
> +      rfn_slot = non_overloaded_function_table->find_slot_with_hash (&rfn, hash,
> +      INSERT);
> +      gcc_assert (!*rfn_slot);
> +      *rfn_slot = &rfn;
>      }
>    obstack_free (&m_string_obstack, name);
> }
> +/* Add overloaded function for gcc. */
> +void
> +function_builder::add_overloaded_function (const function_instance &instance,
> +    const function_shape *shape)
> +{
> +  if (!check_required_extensions (instance))
> +    return;
> +
> +  char *name = shape->get_name (*this, instance, true);
> +
> +  if (name)
> +    {
> +      /* To avoid API conflicting, take void return type and void argument
> + for the overloaded function.  */
> +      tree fntype = build_function_type (void_type_node, void_list_node);
> +      add_function (instance, name, fntype, NULL_TREE, m_direct_overloads, name,
> +     vNULL, true);
> +      obstack_free (&m_string_obstack, name);
> +    }
> +}
> +
> function_call_info::function_call_info (location_t location_in,
> const function_instance &instance_in,
> tree fndecl_in)
> @@ -3991,6 +4067,122 @@ 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)
> +{
> +  if (instance.base->may_require_vxrm_p ()
> +      || (instance.base->may_require_frm_p ()
> +   && (TREE_CODE (TREE_TYPE (arglist[arglist.length () - 2]))
> +       == INTEGER_TYPE)))
> +    return true;
> +  return false;
> +}
> +
> +hashval_t
> +registered_function::overloaded_hash (const vec<tree, va_gc> &arglist)
> +{
> +  argument_types = vNULL;
> +  unsigned int len = arglist.length ();
> +
> +  for (unsigned int i = 0; i < len; i++)
> +    {
> +      /* vint8m1_t __riscv_vget_i8m1(vint8m2_t src, size_t index);
> +      When the user calls vget intrinsic, the __riscv_vget_i8m1(src, 1)
> +       form is used. The compiler recognizes that the parameter index is signed
> +       int, which is inconsistent with size_t, so the index is converted to
> +       size_t type in order to get correct hash value. vint8m2_t
> +       __riscv_vset(vint8m2_t dest, size_t index, vint8m1_t value); The reason
> +       is the same as above. */
> +      if ((instance.base == bases::vget && (i == (len - 1)))
> +   || (instance.base == bases::vset && (i == (len - 2))))
> + argument_types.safe_push (size_type_node);
> +      /* Vector fixed-point arithmetic instructions requiring argument vxrm.
> +      For example: vuint32m4_t __riscv_vaaddu(vuint32m4_t vs2,
> +      vuint32m4_t vs1, unsigned int vxrm, size_t vl); The user calls vaaddu
> +      intrinsic in the form of __riscv_vaaddu(vs2, vs1, 2, vl). The compiler
> +      recognizes that the parameter vxrm is a signed int, which is inconsistent
> +      with the parameter unsigned int vxrm declared by intrinsic, so the
> +      parameter vxrm is converted to an unsigned int type in order to get
> +      correct hash value.
> +
> +      Vector Floating-Point Instructions requiring argument frm.
> +      DEF_RVV_FUNCTION (vfadd, alu, full_preds, f_vvv_ops)
> +      DEF_RVV_FUNCTION (vfadd_frm, alu_frm, full_preds, f_vvv_ops)
> +      Taking vfadd as an example, theoretically we can add base or shape to the
> +      hash value to distinguish whether the frm parameter is required.
> +      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, float32_t rs1, size_t vl);
> +      vfloat32m1_t __riscv_vfadd(vfloat32m1_t vs2, vfloat32m1_t vs1, unsigned int
> +      frm, size_t vl);
> +
> +     However, the current registration mechanism of overloaded intinsic for gcc
> +      limits the intrinsic obtained by entering the hook to always be vfadd, not
> +      vfadd_frm. Therefore, the correct hash value cannot be obtained through the
> +      parameter list and overload name, base or shape.
> +      +--------+---------------------------+-------------------+
> +      | index  | name                      | kind              |
> +      +--------+---------------------------+-------------------+
> +      | 124733 | __riscv_vfadd             | Overloaded        | <- Hook fun code
> +      +--------+---------------------------+-------------------+
> +      | 124735 |  __riscv_vfadd_vv_f32m1   | Non-overloaded    |
> +      +--------+---------------------------+-------------------+
> +      | 124737 | __riscv_vfadd             | Placeholder       |
> +      +--------+---------------------------+-------------------+
> +      | ...                                                    |
> +      +--------+---------------------------+-------------------+
> +      | ...                                                    |
> +      +--------+---------------------------+-------------------+
> +      | 125739 | __riscv_vfadd             | Overloaded        |
> +      +--------+---------------------------+-------------------+
> +      | 125741 | __riscv_vfadd_vv_f32m1_rm | Non-overloaded    |
> +      +--------+---------------------------+-------------------+
> +      | 125743 | __riscv_vfadd             | Placeholder       |
> +      +--------+---------------------------+-------------------+
> +
> +     Therefore, the hash value cannot be added with base or shape, and needs
> +      to be distinguished by whether the penultimate parameter is INTEGER_TYPE. */
> +      else if (has_vxrm_or_frm_p (instance, arglist) && (i == (len - 2)))
> + argument_types.safe_push (unsigned_type_node);
> +      else
> + argument_types.safe_push (TREE_TYPE (arglist[i]));
> +    }
> +  return overloaded_hash ();
> +}
> +
> +inline hashval_t
> +non_overloaded_registered_function_hasher::hash (value_type value)
> +{
> +  return value->overloaded_hash ();
> +}
> +
> +inline bool
> +non_overloaded_registered_function_hasher::equal (value_type value,
> +   const compare_type &key)
> +{
> +  return ((strcmp (value->overload_name, key->overload_name) == 0)
> +   && value->overloaded_hash () == key->overloaded_hash ());
> +}
> +
> /* If TYPE is a built-in type defined by the RVV ABI, return the mangled name,
>     otherwise return NULL.  */
> const char *
> @@ -4139,7 +4331,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 +4348,8 @@ handle_pragma_vector ()
>    /* Define the functions.  */
>    function_table = new hash_table<registered_function_hasher> (1023);
> +  non_overloaded_function_table
> +    = new hash_table<non_overloaded_registered_function_hasher> (1023);
>    function_builder builder;
>    for (unsigned int i = 0; i < ARRAY_SIZE (function_groups); ++i)
>      builder.register_function_group (function_groups[i]);
> @@ -4208,6 +4402,24 @@ check_builtin_call (location_t location, vec<location_t>, unsigned int code,
>    TREE_TYPE (rfn.decl), nargs, args).check ();
> }
> +tree
> +resolve_overloaded_builtin (unsigned int code, vec<tree, va_gc> *arglist)
> +{
> +  if (code >= vec_safe_length (registered_functions))
> +    return NULL_TREE;
> +
> +  registered_function *rfun = (*registered_functions)[code];
> +
> +  if (!rfun || !rfun->overloaded_p)
> +    return NULL_TREE;
> +
> +  hashval_t hash = rfun->overloaded_hash (*arglist);
> +  registered_function *rfn
> +    = non_overloaded_function_table->find_with_hash (rfun, hash);
> +  gcc_assert (rfn);
> +  return rfn->decl;
> +}
> +
> function_instance
> get_read_vl_instance (void)
> {
> diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
> index e358a8e4d91..cd8ccab1724 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.  */
> @@ -417,6 +420,12 @@ public:
>    /* Return true if intrinsics has rounding mode operand.  */
>    virtual bool has_rounding_mode_operand_p () const;
> +  /* Return true if intrinsics maybe require vxrm operand.  */
> +  virtual bool may_require_vxrm_p () const;
> +
> +  /* Return true if intrinsics maybe require frm operand.  */
> +  virtual bool may_require_frm_p () const;
> +
>    /* Try to fold the given gimple call.  Return the new gimple statement
>       on success, otherwise return null.  */
>    virtual gimple *fold (gimple_folder &) const { return NULL; }
> @@ -674,6 +683,22 @@ function_base::has_rounding_mode_operand_p () const
>    return false;
> }
> +/* We choose to return false by default since most of the intrinsics does
> +   not need frm operand.  */
> +inline bool
> +function_base::may_require_frm_p () const
> +{
> +  return false;
> +}
> +
> +/* We choose to return false by default since most of the intrinsics does
> +   not need vxrm operand.  */
> +inline bool
> +function_base::may_require_vxrm_p () const
> +{
> +  return false;
> +}
> +
> /* Since most of intrinsics can be overloaded, we set it true by default.  */
> inline bool
> function_base::can_be_overloaded_p (enum predication_type_index) const
> 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
>  
>  

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2023-11-06  2:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-31  9:03 [PATCH v6] RISC-V: Implement RESOLVE_OVERLOADED_BUILTIN for RVV intrinsic Li Xu
2023-10-31  9:07 ` juzhe.zhong
2023-10-31 11:36   ` Li Xu
2023-10-31 12:35     ` Li, Pan2
2023-11-01  0:26     ` juzhe.zhong
2023-11-06  1:26     ` juzhe.zhong
2023-11-06  2:31       ` Li Xu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).