This commit adds intrinsic support for Zvabd.  The original vwabad
machine description pattern would cause an ICE when emitting the
intrinsic because operand 0 and operand 2 are different pseudos,
and operand 2 has a constraint of "0", while operand 0 is marked as
read-write "-".  The vwmacc-like pattern is now used to support correct
intrinsic generation and to better reflect the semantics.

gcc/ChangeLog:

        * config/riscv/autovec-opt.md: Match the new vwmacc-like pattern.
        * config/riscv/genrvv-type-indexer.cc: Support
        DOUBLE_TRUNC_SIGNED type for v[u]int types.
        * config/riscv/riscv-vector-builtins-bases.cc (class vabd): New
        class.
        (class vabs): Ditto.
        (class vabda): Ditto.
        (BASE): Define.
        * config/riscv/riscv-vector-builtins-bases.h: Ditto.
        * config/riscv/riscv-vector-builtins-functions.def 
(REQUIRED_EXTENSIONS):
        Ditto.
        (vabs): Ditto.
        (vabd): Ditto.
        (vabdu): Ditto.
        (vwabda): Ditto.
        (vwabdau): Ditto.
        * config/riscv/riscv-vector-builtins-shapes.cc (struct xt_alu_u_def):
        Change definition.
        (struct alu_u_def): Define.
        (SHAPE): New shape.
        * config/riscv/riscv-vector-builtins-shapes.h: Ditto.
        * config/riscv/riscv-vector-builtins-types.def (DEF_RVV_QI_HI_OPS):
        Define.
        (DEF_RVV_QU_HU_OPS): Ditto.
        (DEF_RVV_HI_SI_OPS): Ditto.
        (DEF_RVV_HU_SU_OPS): Ditto.
        * config/riscv/riscv-vector-builtins.cc (DEF_RVV_QI_HI_OPS):
        Ditto.
        (DEF_RVV_QU_HU_OPS): Ditto.
        (DEF_RVV_HI_SI_OPS): Ditto.
        (DEF_RVV_HU_SU_OPS): Ditto.
        (get_builtin_partition): Add Zvabd case.
        * config/riscv/riscv-vector-builtins.h (enum required_ext):
        Ditto.
        (enum rvv_builtin_partition): Ditto.
        (required_ext_to_isa_name): Ditto.
        (required_extensions_specified): Ditto.
        * config/riscv/vector.md: Rewrite pred_widen_abd_plus as
        vwmacc-like form.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/base/intrinsic-detection.c: Add Zvabd.
        * gcc.target/riscv/rvv/base/zvabd-intrinsic.c: New test.
---
 gcc/config/riscv/autovec-opt.md               |  8 +--
 gcc/config/riscv/genrvv-type-indexer.cc       |  5 +-
 .../riscv/riscv-vector-builtins-bases.cc      | 48 +++++++++++++
 .../riscv/riscv-vector-builtins-bases.h       |  6 ++
 .../riscv/riscv-vector-builtins-functions.def |  9 +++
 .../riscv/riscv-vector-builtins-types.def     | 40 +++++++++++
 gcc/config/riscv/riscv-vector-builtins.cc     | 70 +++++++++++++++++++
 gcc/config/riscv/riscv-vector-builtins.h      |  6 ++
 gcc/config/riscv/vector.md                    | 20 +++---
 .../riscv/rvv/base/intrinsic-detection.c      |  5 +-
 .../riscv/rvv/base/zvabd-intrinsic.c          | 54 ++++++++++++++
 11 files changed, 255 insertions(+), 16 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/zvabd-intrinsic.c

diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index d210b05a8a2..094ad6fd6c9 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -698,9 +698,9 @@ (define_insn_and_split "*vwabda<su><mode>"
   "&& 1"
   [(const_int 0)]
 {
-  rtx ops[] = {operands[0], operands[1], operands[2]};
+  rtx ops[] = {operands[0], operands[3], operands[1], operands[2]};
   riscv_vector::emit_vlmax_insn (CODE_FOR_pred_widen_abd_plus<su><mode>,
-                                riscv_vector::BINARY_OP, ops);
+                                riscv_vector::WIDEN_TERNARY_OP, ops);
   DONE;
 }
 [(set_attr "type" "viwalu")])
@@ -720,9 +720,9 @@ (define_insn_and_split "*vwabda_right<su><mode>"
   "&& 1"
   [(const_int 0)]
 {
-  rtx ops[] = {operands[0], operands[2], operands[3]};
+  rtx ops[] = {operands[0], operands[1], operands[2], operands[3]};
   riscv_vector::emit_vlmax_insn (CODE_FOR_pred_widen_abd_plus<su><mode>,
-                                riscv_vector::BINARY_OP, ops);
+                                riscv_vector::WIDEN_TERNARY_OP, ops);
   DONE;
 }
 [(set_attr "type" "viwalu")])
diff --git a/gcc/config/riscv/genrvv-type-indexer.cc 
b/gcc/config/riscv/genrvv-type-indexer.cc
index ddc0d9863fc..413ca19a171 100644
--- a/gcc/config/riscv/genrvv-type-indexer.cc
+++ b/gcc/config/riscv/genrvv-type-indexer.cc
@@ -376,7 +376,10 @@ main (int argc, const char **argv)
                     same_ratio_eew_type (sew, lmul_log2, sew / 2, unsigned_p,
                                          false)
                       .c_str ());
-           fprintf (fp, "  /*DOUBLE_TRUNC_SIGNED*/ INVALID,\n");
+           fprintf (fp, "  /*DOUBLE_TRUNC_SIGNED*/ %s,\n",
+                    same_ratio_eew_type (sew, lmul_log2, sew / 2, false,
+                                         false)
+                      .c_str ());
            fprintf (fp, "  /*DOUBLE_TRUNC_UNSIGNED*/ %s,\n",
                     same_ratio_eew_type (sew, lmul_log2, sew / 2, true, false)
                       .c_str ());
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc 
b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index 6e3b3a01862..3bbec005fac 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -2462,6 +2462,41 @@ public:
   }
 };
 
+/* Implements vabd/vabdu.  */
+template<int UNSPEC>
+class vabd : public function_base
+{
+public:
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_vabd (UNSPEC, e.vector_mode ()));
+  }
+};
+
+/* Implements vabs.  */
+class vabs : public function_base
+{
+public:
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_abs (e.vector_mode ()));
+  }
+};
+
+/* Implements vwabda/vwabdau.  */
+template<int UNSPEC>
+class vabda : public function_base
+{
+public:
+  bool has_merge_operand_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_widen_ternop_insn (
+      code_for_pred_widen_abd_plus (UNSPEC, e.vector_mode ()));
+  }
+};
+
 static constexpr const vsetvl<false> vsetvl_obj;
 static constexpr const vsetvl<true> vsetvlmax_obj;
 static constexpr const loadstore<false, LST_UNIT_STRIDE, false> vle_obj;
@@ -2787,6 +2822,13 @@ static constexpr const vfwcvtbf16_f vfwcvtbf16_f_obj;
 static constexpr const vfwmaccbf16<NO_FRM> vfwmaccbf16_obj;
 static constexpr const vfwmaccbf16<HAS_FRM> vfwmaccbf16_frm_obj;
 
+/* Zvabd */
+static constexpr const vabs vabs_obj;
+static constexpr const vabd<UNSPEC_VSABD> vabd_obj;
+static constexpr const vabd<UNSPEC_VUABD> vabdu_obj;
+static constexpr const vabda<UNSPEC_VSABDA> vwabda_obj;
+static constexpr const vabda<UNSPEC_VUABDA> vwabdau_obj;
+
 /* Declare the function base NAME, pointing it to an instance
    of class <NAME>_obj.  */
 #define BASE(NAME) \
@@ -3114,4 +3156,10 @@ BASE (vfwcvtbf16_f)
 /* Zvfbfwma */
 BASE (vfwmaccbf16)
 BASE (vfwmaccbf16_frm)
+/* Zvabd.  */
+BASE (vabs)
+BASE (vabd)
+BASE (vabdu)
+BASE (vwabda)
+BASE (vwabdau)
 } // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h 
b/gcc/config/riscv/riscv-vector-builtins-bases.h
index 9261d353e22..d7a727d6bc5 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.h
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.h
@@ -352,6 +352,12 @@ extern const function_base *const vfwcvtbf16_f;
 /* Zvfbfwma */
 extern const function_base *const vfwmaccbf16;
 extern const function_base *const vfwmaccbf16_frm;
+/* Zvabd */
+extern const function_base *const vabs;
+extern const function_base *const vabd;
+extern const function_base *const vabdu;
+extern const function_base *const vwabda;
+extern const function_base *const vwabdau;
 }
 
 } // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def 
b/gcc/config/riscv/riscv-vector-builtins-functions.def
index f64d42d1823..61b8e933a15 100644
--- a/gcc/config/riscv/riscv-vector-builtins-functions.def
+++ b/gcc/config/riscv/riscv-vector-builtins-functions.def
@@ -776,4 +776,13 @@ DEF_RVV_FUNCTION (vfwmaccbf16, alu, full_preds, 
f32_wwfv_ops)
 DEF_RVV_FUNCTION (vfwmaccbf16_frm, alu_frm, full_preds, f32_wwvv_ops)
 DEF_RVV_FUNCTION (vfwmaccbf16_frm, alu_frm, full_preds, f32_wwfv_ops)
 #undef REQUIRED_EXTENSIONS
+
+/* Zvabd */
+#define REQUIRED_EXTENSIONS ZVABD_EXT
+DEF_RVV_FUNCTION (vabs,    alu, full_preds, u_v_signed_ops)
+DEF_RVV_FUNCTION (vabd,    alu, full_preds, qu_hu_vvv_signed_ops)
+DEF_RVV_FUNCTION (vabdu,   alu, full_preds, qu_hu_vvv_ops)
+DEF_RVV_FUNCTION (vwabda,  alu, full_preds, hu_su_wwvv_signed_ops)
+DEF_RVV_FUNCTION (vwabdau, alu, full_preds, hu_su_wwvv_ops)
+#undef REQUIRED_EXTENSIONS
 #undef DEF_RVV_FUNCTION
diff --git a/gcc/config/riscv/riscv-vector-builtins-types.def 
b/gcc/config/riscv/riscv-vector-builtins-types.def
index fd64771de9e..2e952bedca1 100644
--- a/gcc/config/riscv/riscv-vector-builtins-types.def
+++ b/gcc/config/riscv/riscv-vector-builtins-types.def
@@ -399,6 +399,18 @@ along with GCC; see the file COPYING3.  If not see
 #define DEF_RVV_F16_OPS(TYPE, REQUIRE)
 #endif
 
+/* Use "DEF_RVV_QU_HU_OPS" macro include all types for vuint8 and vuint16
+   which will be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_QU_HU_OPS
+#define DEF_RVV_QU_HU_OPS(TYPE, REQUIRE)
+#endif
+
+/* Use "DEF_RVV_HU_SU_OPS" macro include all types for vuint16 and vuint32
+   which will be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_HU_SU_OPS
+#define DEF_RVV_HU_SU_OPS(TYPE, REQUIRE)
+#endif
+
 DEF_RVV_I_OPS (vint8mf8_t, RVV_REQUIRE_ELEN_64)
 DEF_RVV_I_OPS (vint8mf4_t, 0)
 DEF_RVV_I_OPS (vint8mf2_t, 0)
@@ -1542,6 +1554,32 @@ DEF_RVV_F16_OPS (vfloat16m2_t, RVV_REQUIRE_ELEN_FP_16)
 DEF_RVV_F16_OPS (vfloat16m4_t, RVV_REQUIRE_ELEN_FP_16)
 DEF_RVV_F16_OPS (vfloat16m8_t, RVV_REQUIRE_ELEN_FP_16)
 
+DEF_RVV_QU_HU_OPS (vuint8mf8_t, RVV_REQUIRE_ELEN_64)
+DEF_RVV_QU_HU_OPS (vuint8mf4_t, 0)
+DEF_RVV_QU_HU_OPS (vuint8mf2_t, 0)
+DEF_RVV_QU_HU_OPS (vuint8m1_t, 0)
+DEF_RVV_QU_HU_OPS (vuint8m2_t, 0)
+DEF_RVV_QU_HU_OPS (vuint8m4_t, 0)
+DEF_RVV_QU_HU_OPS (vuint8m8_t, 0)
+DEF_RVV_QU_HU_OPS (vuint16mf4_t, RVV_REQUIRE_ELEN_64)
+DEF_RVV_QU_HU_OPS (vuint16mf2_t, 0)
+DEF_RVV_QU_HU_OPS (vuint16m1_t, 0)
+DEF_RVV_QU_HU_OPS (vuint16m2_t, 0)
+DEF_RVV_QU_HU_OPS (vuint16m4_t, 0)
+DEF_RVV_QU_HU_OPS (vuint16m8_t, 0)
+
+DEF_RVV_HU_SU_OPS (vuint16mf4_t, RVV_REQUIRE_ELEN_64)
+DEF_RVV_HU_SU_OPS (vuint16mf2_t, 0)
+DEF_RVV_HU_SU_OPS (vuint16m1_t, 0)
+DEF_RVV_HU_SU_OPS (vuint16m2_t, 0)
+DEF_RVV_HU_SU_OPS (vuint16m4_t, 0)
+DEF_RVV_HU_SU_OPS (vuint16m8_t, 0)
+DEF_RVV_HU_SU_OPS (vuint32mf2_t, RVV_REQUIRE_ELEN_64)
+DEF_RVV_HU_SU_OPS (vuint32m1_t, 0)
+DEF_RVV_HU_SU_OPS (vuint32m2_t, 0)
+DEF_RVV_HU_SU_OPS (vuint32m4_t, 0)
+DEF_RVV_HU_SU_OPS (vuint32m8_t, 0)
+
 #undef DEF_RVV_I_OPS
 #undef DEF_RVV_U_OPS
 #undef DEF_RVV_F_OPS
@@ -1603,3 +1641,5 @@ DEF_RVV_F16_OPS (vfloat16m8_t, RVV_REQUIRE_ELEN_FP_16)
 #undef DEF_RVV_Q_OPS
 #undef DEF_RVV_QU_OPS
 #undef DEF_RVV_F16_OPS
+#undef DEF_RVV_QU_HU_OPS
+#undef DEF_RVV_HU_SU_OPS
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc 
b/gcc/config/riscv/riscv-vector-builtins.cc
index 47f80be5a39..a3b74259b46 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -590,6 +590,20 @@ static const rvv_type_info f16_ops[] = {
 #include "riscv-vector-builtins-types.def"
   {NUM_VECTOR_TYPES, 0}};
 
+/* A list of all vuint8m_t and vuint16m_t will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info qu_hu_ops[] = {
+#define DEF_RVV_QU_HU_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
+/* A list of all vuint16m_t and vuint32m_t will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info hu_su_ops[] = {
+#define DEF_RVV_HU_SU_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
 static constexpr const rvv_arg_type_info rvv_arg_type_info_end
   = rvv_arg_type_info (NUM_BASE_TYPES);
 
@@ -1266,6 +1280,20 @@ static constexpr const rvv_arg_type_info vw_args[]
   = {rvv_arg_type_info (RVV_BASE_vector),
      rvv_arg_type_info (RVV_BASE_float32), rvv_arg_type_info_end};
 
+/* A list of args for vector_type func (signed vector_type, signed
+   vector_type) function.  */
+static constexpr const rvv_arg_type_info signed_vv_args[]
+  = {rvv_arg_type_info (RVV_BASE_signed_vector),
+     rvv_arg_type_info (RVV_BASE_signed_vector), rvv_arg_type_info_end};
+
+/* A list of args for vector_type func (vector_type, signed double demote type,
+   signed double demote type) function.  */
+static constexpr const rvv_arg_type_info signed_narrow_wwvv_args[]
+  = {rvv_arg_type_info (RVV_BASE_vector),
+     rvv_arg_type_info (RVV_BASE_double_trunc_signed_vector),
+     rvv_arg_type_info (RVV_BASE_double_trunc_signed_vector),
+     rvv_arg_type_info_end};
+
 /* A list of none preds that will be registered for intrinsic functions.  */
 static constexpr const predication_type_index none_preds[]
   = {PRED_TYPE_none, NUM_PRED_TYPES};
@@ -3441,6 +3469,46 @@ static constexpr const rvv_op_info sf_vc_v_fvw_ops
      rvv_arg_type_info (RVV_BASE_x2_vector), /* Return type */
      sf_vc_fvw_args /* Args */};
 
+/* A static operand information for vector_type func (signed vector_type,
+   signed vector_type) function registration.  */
+static constexpr const rvv_op_info qu_hu_vvv_signed_ops
+  = {qu_hu_ops,                        /* Types */
+     OP_TYPE_vv,                       /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     signed_vv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, vector_type)
+ * function registration.  */
+static constexpr const rvv_op_info qu_hu_vvv_ops
+  = {qu_hu_ops,                        /* Types */
+     OP_TYPE_vv,                       /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, signed
+   double demote type, signed double demote type) function registration.  */
+static constexpr const rvv_op_info hu_su_wwvv_signed_ops
+  = {hu_su_ops,                                  /* Types */
+     OP_TYPE_vv,                         /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     signed_narrow_wwvv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type, double 
demote
+ * type, double demote type) function registration.  */
+static constexpr const rvv_op_info hu_su_wwvv_ops
+  = {hu_su_ops,                                  /* Types */
+     OP_TYPE_vv,                         /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     wwvv_args /* Args */};
+
+/* A static operand information for vector_type func (signed vector_type)
+   function registration.  */
+static constexpr const rvv_op_info u_v_signed_ops
+  = {u_ops,                            /* Types */
+     OP_TYPE_v,                        /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     x_v_args /* Args */};
+
 /* A list of all RVV base function types.  */
 static constexpr const function_type_info function_types[] = {
 #define DEF_RVV_TYPE_INDEX(                                                    
\
@@ -3656,6 +3724,8 @@ get_builtin_partition (required_ext ext, const 
function_instance &instance)
       return RVV_PARTITION_ZVFBFWMA;
     case ZVFOFP8MIN_EXT:
       return RVV_PARTITION_ZVFOFP8MIN;
+    case ZVABD_EXT:
+      return RVV_PARTITION_ZVABD;
     case XSFVQMACCQOQ_EXT:
       return RVV_PARTITION_XSFVQMACCQOQ;
     case XSFVQMACCDOD_EXT:
diff --git a/gcc/config/riscv/riscv-vector-builtins.h 
b/gcc/config/riscv/riscv-vector-builtins.h
index dfc3e8703b3..8e5cba1e1b6 100644
--- a/gcc/config/riscv/riscv-vector-builtins.h
+++ b/gcc/config/riscv/riscv-vector-builtins.h
@@ -131,6 +131,7 @@ enum required_ext
   ZVFBFMIN_EXT,                /* Zvfbfmin extension */
   ZVFBFWMA_EXT,                /* Zvfbfwma extension */
   ZVFOFP8MIN_EXT,      /* Zvfofp8min extension */
+  ZVABD_EXT,           /* Zvabd extension */
   XSFVQMACCQOQ_EXT,    /* XSFVQMACCQOQ extension */
   XSFVQMACCDOD_EXT,    /* XSFVQMACCDOD extension */
   XSFVFNRCLIPXFQF_EXT, /* XSFVFNRCLIPXFQF extension */
@@ -162,6 +163,7 @@ enum rvv_builtin_partition
   RVV_PARTITION_ZVFHMIN,
   RVV_PARTITION_ZVFH,
   RVV_PARTITION_ZVFOFP8MIN,
+  RVV_PARTITION_ZVABD,
   RVV_PARTITION_XSFVQMACCQOQ,
   RVV_PARTITION_XSFVQMACCDOD,
   RVV_PARTITION_XSFVFNRCLIPXFQF,
@@ -216,6 +218,8 @@ static inline const char * required_ext_to_isa_name (enum 
required_ext required)
       return "zvfbfwma";
     case ZVFOFP8MIN_EXT:
       return "zvfofp8min";
+    case ZVABD_EXT:
+      return "zvabd";
     case XSFVQMACCQOQ_EXT:
       return "xsfvqmaccqoq";
     case XSFVQMACCDOD_EXT:
@@ -273,6 +277,8 @@ static inline bool required_extensions_specified (enum 
required_ext required)
       return TARGET_ZVFBFWMA;
     case ZVFOFP8MIN_EXT:
       return TARGET_ZVFOFP8MIN;
+    case ZVABD_EXT:
+      return TARGET_ZVABD;
     case XSFVQMACCQOQ_EXT:
       return TARGET_XSFVQMACCQOQ;
     case XSFVQMACCDOD_EXT:
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 5225e85ed61..56bfe044e24 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -9285,22 +9285,22 @@ (define_insn "@pred_vabd<su><mode>"
    (set_attr "mode" "<MODE>")])
 
 (define_insn "@pred_widen_abd_plus<su><mode>"
-  [(set (match_operand:VWEXTI_HS 0 "register_operand"      "+&vd,&vd,&vr,&vr")
+  [(set (match_operand:VWEXTI_HS 0 "register_operand"    "=&vr")
        (if_then_else:VWEXTI_HS
          (unspec:<VM>
-           [(match_operand:<VM> 1 "vector_mask_operand" "vm,vm,Wc1,Wc1")
-            (match_operand 5 "vector_length_operand"    "rK,rK,rK,rK")
-            (match_operand 6 "const_int_operand"      "i,i,i,i")
-            (match_operand 7 "const_int_operand"      "i,i,i,i")
-            (match_operand 8 "const_int_operand"      "i,i,i,i")
+           [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+            (match_operand 5 "vector_length_operand"    "  rK")
+            (match_operand 6 "const_int_operand"        "   i")
+            (match_operand 7 "const_int_operand"        "   i")
+            (match_operand 8 "const_int_operand"        "   i")
             (reg:SI VL_REGNUM)
             (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
          (unspec:VWEXTI_HS
-           [(match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" "vr,vr,vr,vr")
-            (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" "vr,vr,vr,vr")
-            (match_dup 0)]
+           [(match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" "  vr")
+            (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" "  vr")
+            (match_operand:VWEXTI_HS 2 "register_operand"        "   0")]
            UNSPEC_VABDA)
-         (match_operand:VWEXTI_HS 2 "vector_merge_operand" "vu,0,vu,0")))]
+         (match_dup 2)))]
   "TARGET_ZVABD"
   "vwabda<u>.vv\t%0,%3,%4%p1"
   [(set_attr "type" "viwalu")
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic-detection.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic-detection.c
index d11cd26afa3..4ba99664ed1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic-detection.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic-detection.c
@@ -5,7 +5,8 @@
 #include <sifive_vector.h>
 #include <andes_vector.h>
 
-#if defined (__riscv_vector) || defined (__riscv_zvbb) \
+#if defined (__riscv_vector) || defined (__riscv_zvabd) \
+    || defined (__riscv_zvbb) \
     || defined (__riscv_zve32f) || defined (__riscv_zve32x) \
     || defined (__riscv_zve64d) || defined (__riscv_zve64f) \
     || defined (__riscv_zve64x) \
@@ -24,6 +25,7 @@
     || !defined (__riscv_intrinsic_zve64d) \
     || !defined (__riscv_intrinsic_zve64f) \
     || !defined (__riscv_intrinsic_zve64x) \
+    || !defined (__riscv_intrinsic_zvabd) \
     || !defined (__riscv_intrinsic_zvbb) \
     || !defined (__riscv_intrinsic_zvbc) \
     || !defined (__riscv_intrinsic_zvfbfmin) \
@@ -60,6 +62,7 @@
     || __riscv_intrinsic_zve64d != 1 \
     || __riscv_intrinsic_zve64f != 1 \
     || __riscv_intrinsic_zve64x != 1 \
+    || __riscv_intrinsic_zvabd != 1 \
     || __riscv_intrinsic_zvbb != 1 \
     || __riscv_intrinsic_zvbc != 1 \
     || __riscv_intrinsic_zvfbfmin != 1 \
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/zvabd-intrinsic.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/zvabd-intrinsic.c
new file mode 100644
index 00000000000..389c106d560
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/zvabd-intrinsic.c
@@ -0,0 +1,54 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvabd -mabi=lp64d" } */
+#include <riscv_vector.h>
+
+vuint8m1_t
+test_vabs_v_u8m1 (vint8m1_t vs2, size_t vl)
+{
+  return __riscv_vabs_v_u8m1 (vs2, vl);
+}
+
+vuint64m1_t
+test_vabs_v_u64m1_m (vbool64_t mask, vint64m1_t vs2, size_t vl)
+{
+  return __riscv_vabs_v_u64m1_m (mask, vs2, vl);
+}
+
+vuint16m1_t
+test_vabd_vv_u16m1 (vint16m1_t vs2, vint16m1_t vs1, size_t vl)
+{
+  return __riscv_vabd_vv_u16m1 (vs2, vs1, vl);
+}
+
+vuint8m1_t
+test_vabd_vv_u8m1_m (vbool8_t mask, vint8m1_t vs2,
+                     vint8m1_t vs1, size_t vl)
+{
+  return __riscv_vabd_vv_u8m1_m (mask, vs2, vs1, vl);
+}
+
+vuint16m1_t
+test_vabdu_vv_u16m1 (vuint16m1_t vs2, vuint16m1_t vs1, size_t vl)
+{
+  return __riscv_vabdu_vv_u16m1 (vs2, vs1, vl);
+}
+
+vuint32m1_t
+test_vwabda_vv_u32m1 (vuint32m1_t vd, vint16mf2_t vs2,
+                      vint16mf2_t vs1, size_t vl)
+{
+  return __riscv_vwabda_vv_u32m1 (vd, vs2, vs1, vl);
+}
+
+vuint16m1_t
+test_vwabdau_vv_u16m1 (vuint16m1_t vd, vuint8mf2_t vs2,
+                       vuint8mf2_t vs1, size_t vl)
+{
+  return __riscv_vwabdau_vv_u16m1 (vd, vs2, vs1, vl);
+}
+
+/* { dg-final { scan-assembler-times {\tvabs\.v} 2 } } */
+/* { dg-final { scan-assembler-times {\tvabd\.vv} 2 } } */
+/* { dg-final { scan-assembler-times {\tvabdu\.vv} 1 } } */
+/* { dg-final { scan-assembler-times {\tvwabda\.vv} 1 } } */
+/* { dg-final { scan-assembler-times {\tvwabdau\.vv} 1 } } */
-- 
2.46.0

Reply via email to