]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Add intrinsic support for Zvabd
authorBohan Lei <garthlei@linux.alibaba.com>
Thu, 23 Jul 2026 01:36:30 +0000 (09:36 +0800)
committerBohan Lei <garthlei@linux.alibaba.com>
Thu, 30 Jul 2026 10:10:28 +0000 (18:10 +0800)
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.  Pan Li's new
overlap constraint is used according to Robin's review comments of v2.

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-types.def (DEF_RVV_QU_HU_OPS):
Define.
(DEF_RVV_HU_SU_OPS): Ditto.
* config/riscv/riscv-vector-builtins.cc (qu_hu_ops): Ditto.
(hu_su_ops): Ditto.
(ss_args): Ditto.
(wwss_args): Ditto.
(qu_hu_vss_ops): Ditto
(qu_hu_vvv_ops): Ditto
(hu_su_wwss_ops): Ditto
(hu_su_wwvv_ops): Ditto
(u_s_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/riscv_vector.h (__riscv_intrinsic_zvabd): Define.
* 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.

12 files changed:
gcc/config/riscv/autovec-opt.md
gcc/config/riscv/genrvv-type-indexer.cc
gcc/config/riscv/riscv-vector-builtins-bases.cc
gcc/config/riscv/riscv-vector-builtins-bases.h
gcc/config/riscv/riscv-vector-builtins-functions.def
gcc/config/riscv/riscv-vector-builtins-types.def
gcc/config/riscv/riscv-vector-builtins.cc
gcc/config/riscv/riscv-vector-builtins.h
gcc/config/riscv/riscv_vector.h
gcc/config/riscv/vector.md
gcc/testsuite/gcc.target/riscv/rvv/base/intrinsic-detection.c
gcc/testsuite/gcc.target/riscv/rvv/base/zvabd-intrinsic.c [new file with mode: 0644]

index d210b05a8a2a460f54d284a5432ee8a76bb2e3c8..094ad6fd6c94a9b42ccced8b48f6cd8ea4a49135 100644 (file)
   "&& 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")])
   "&& 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")])
index ddc0d9863fca9a5be4afe04e7f3749bb631da347..413ca19a1719265e621a476dd43314137623647a 100644 (file)
@@ -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 ());
index 6e3b3a01862e1ac27ceb7e33c6c220e6efc51f55..3bbec005facfe088ad3d09e58f2244a2525c8455 100644 (file)
@@ -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
index 9261d353e2207ba8d05f855c9a34eb48ea95563f..d7a727d6bc5b0c1323a2c82cca6452a1382339a1 100644 (file)
@@ -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
index f64d42d182385674a137e9592344e3e1f47b5b0b..a31e1c4e194cfe79b98c4c5dd93a2f63c665c86e 100644 (file)
@@ -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_s_ops)
+DEF_RVV_FUNCTION (vabd,    alu, full_preds, qu_hu_vss_ops)
+DEF_RVV_FUNCTION (vabdu,   alu, full_preds, qu_hu_vvv_ops)
+DEF_RVV_FUNCTION (vwabda,  alu, full_preds, hu_su_wwss_ops)
+DEF_RVV_FUNCTION (vwabdau, alu, full_preds, hu_su_wwvv_ops)
+#undef REQUIRED_EXTENSIONS
 #undef DEF_RVV_FUNCTION
index fd64771de9e0a4095a935671cf0698af1c0735b5..2e952bedca16a48d646371e5fdedd119561003b9 100644 (file)
@@ -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
index 47f80be5a392eecc7fde4fa574420f23904792b1..a7e5c24281fd016f8bdfa3657d414bebc339fd8f 100644 (file)
@@ -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 ss_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 wwss_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_vss_ops
+  = {qu_hu_ops,                        /* Types */
+     OP_TYPE_vv,                       /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     ss_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_wwss_ops
+  = {hu_su_ops,                                  /* Types */
+     OP_TYPE_vv,                         /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     wwss_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_s_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:
index dfc3e8703b3d0afffd449045982b5fc04589cf4a..8e5cba1e1b629af9b61c2b5b9cb3b2873a67b2da 100644 (file)
@@ -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:
index bda75833ef2eb22feefcab0b225fb34f8d1adb04..8dd0ac46d989b4604f5a23fec5d01fdb107c56ef 100644 (file)
@@ -47,6 +47,7 @@
 #define __riscv_intrinsic_zvknhb 1
 #define __riscv_intrinsic_zvksed 1
 #define __riscv_intrinsic_zvksh 1
+#define __riscv_intrinsic_zvabd 1
 
 #if defined (__riscv_intrinsic_zvkned) \
     && defined (__riscv_intrinsic_zvknhb) \
index ae8672999ebb24dee954a8e4302a529ae5458c4e..04684c458a735a34e59f0ffb31f6d2ede70d7fd5 100644 (file)
    (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"    "=vd,  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" " vm, Wc1")
+            (match_operand 5 "vector_length_operand"    "rvl, rvl")
+            (match_operand 6 "const_int_operand"        " i,    i")
+            (match_operand 7 "const_int_operand"        " i,    i")
+            (match_operand 8 "const_int_operand"        " i,    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" "Wvr, Wvr")
+            (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" "Wvr, Wvr")
+            (match_operand:VWEXTI_HS 2 "register_operand"        "  0,   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")
index d11cd26afa38915da9343606edadb79b2935888f..4ba99664ed1ebe3715563b022d6183948ebea2bc 100644 (file)
@@ -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 (file)
index 0000000..37f9174
--- /dev/null
@@ -0,0 +1,92 @@
+/* { 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);
+}
+
+vuint8m1_t
+test_vabs_v_u8m1_tumu (vbool8_t mask, vuint8m1_t vd, vint8m1_t vs2, size_t vl)
+{
+  return __riscv_vabs_v_u8m1_tumu (mask, vd, vs2, vl);
+}
+
+vuint16m1_t
+test_vabs_v_u16m1_tu (vuint16m1_t vd, vint16m1_t vs2, size_t vl)
+{
+  return __riscv_vabs_v_u16m1_tu (vd, vs2, vl);
+}
+
+vuint32m1_t
+test_vabs_v_u32m1_mu (vbool32_t mask, vuint32m1_t vd, vint32m1_t vs2, size_t vl)
+{
+  return __riscv_vabs_v_u32m1_mu (mask, vd, 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);
+}
+
+vuint16m1_t
+test_vabdu_vv_u16m1_tu (vuint16m1_t vd, vuint16m1_t vs2, vuint16m1_t vs1,
+                       size_t vl)
+{
+  return __riscv_vabdu_vv_u16m1_tu (vd, 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_vwabda_vv_u16m1_tu (vuint16m1_t vd, vint8mf2_t vs2, vint8mf2_t vs1,
+                        size_t vl)
+{
+  return __riscv_vwabda_vv_u16m1_tu (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);
+}
+
+vuint16m1_t
+test_vwabdau_vv_u16m1_mu (vbool16_t mask, vuint16m1_t vd, vuint8mf2_t vs2,
+                         vuint8mf2_t vs1, size_t vl)
+{
+  return __riscv_vwabdau_vv_u16m1_mu (mask, vd, vs2, vs1, vl);
+}
+
+/* { dg-final { scan-assembler-times {\tvabs\.v} 5 } } */
+/* { dg-final { scan-assembler-times {\tvabd\.vv} 2 } } */
+/* { dg-final { scan-assembler-times {\tvabdu\.vv} 2 } } */
+/* { dg-final { scan-assembler-times {\tvwabda\.vv} 2 } } */
+/* { dg-final { scan-assembler-times {\tvwabdau\.vv} 2 } } */