Hi,

this patch implements autovec expanders of abs<mode>2, vneg<mode>2 and
vnot<mode>2 for integers.  I also tried to refactor the helper code
in riscv-v.cc a bit.  Guess it's not enough to warrant a separate patch
though.

Regards
 Robin 

gcc/ChangeLog:

        * config/riscv/autovec.md (<optab><mode>2): Fix typo.
        (abs<mode>2): New expander.
        * config/riscv/riscv-protos.h (emit_len_masked_op): Declare.
        (emit_len_cmp): Declare.
        (enum tail_policy): Add undefined.
        (enum mask_policy): Add undefined.
        * config/riscv/riscv-v.cc (const_vlmax_p): Fix typo.
        (emit_pred_op): Swap mask and dest.
        (emit_pred_binop): Dito.
        (emit_pred_cmp_op): Dito.
        (emit_vlmax_reg_op): Dito.
        (emit_len_masked_op): New function.
        (emit_len_cmp): New function.
        (emit_index_op): Use helper function.
        (get_prefer_tail_policy): Rename.
        (get_preferred_tail_policy): To this.
        (get_prefer_mask_policy): Rename.
        (get_preferred_mask_policy): To this.
        (slide1_sew64_helper): Dito.
        * config/riscv/riscv-vector-builtins.cc (get_tail_policy_for_pred):
        Dito.
        (get_mask_policy_for_pred): Dito.
        * config/riscv/riscv-vsetvl.cc (get_default_ta): Dito.
        (get_default_ma): Dito.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/autovec/unop/abs-run.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/abs-rv32gcv.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/abs-rv64gcv.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/abs-template.h: New test.
        * gcc.target/riscv/rvv/autovec/unop/vneg-run.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/vneg-rv32gcv.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/vneg-rv64gcv.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/vneg-template.h: New test.
        * gcc.target/riscv/rvv/autovec/unop/vnot-run.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/vnot-rv32gcv.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/vnot-rv64gcv.c: New test.
        * gcc.target/riscv/rvv/autovec/unop/vnot-template.h: New test.
---
 gcc/config/riscv/autovec.md                   |  51 +++++-
 gcc/config/riscv/riscv-protos.h               |   8 +-
 gcc/config/riscv/riscv-v.cc                   | 146 ++++++++++++++----
 gcc/config/riscv/riscv-vector-builtins.cc     |   4 +-
 gcc/config/riscv/riscv-vsetvl.cc              |   8 +-
 .../riscv/rvv/autovec/unop/abs-run.c          |  29 ++++
 .../riscv/rvv/autovec/unop/abs-rv32gcv.c      |   7 +
 .../riscv/rvv/autovec/unop/abs-rv64gcv.c      |   7 +
 .../riscv/rvv/autovec/unop/abs-template.h     |  26 ++++
 .../riscv/rvv/autovec/unop/vneg-run.c         |  29 ++++
 .../riscv/rvv/autovec/unop/vneg-rv32gcv.c     |   6 +
 .../riscv/rvv/autovec/unop/vneg-rv64gcv.c     |   6 +
 .../riscv/rvv/autovec/unop/vneg-template.h    |  17 ++
 .../riscv/rvv/autovec/unop/vnot-run.c         |  33 ++++
 .../riscv/rvv/autovec/unop/vnot-rv32gcv.c     |   6 +
 .../riscv/rvv/autovec/unop/vnot-rv64gcv.c     |   6 +
 .../riscv/rvv/autovec/unop/vnot-template.h    |  21 +++
 gcc/testsuite/gcc.target/riscv/rvv/rvv.exp    |   2 +
 18 files changed, 377 insertions(+), 35 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-run.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-rv32gcv.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-rv64gcv.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-template.h
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-run.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-rv32gcv.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-rv64gcv.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-template.h
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-run.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-rv32gcv.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-rv64gcv.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-template.h

diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index ce0b46537ad..8060a5cdf90 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -161,7 +161,7 @@ (define_expand "<optab><mode>3"
 })
 
 ;; -------------------------------------------------------------------------
-;; ---- [INT] Binary shifts by scalar.
+;; ---- [INT] Binary shifts by vector.
 ;; -------------------------------------------------------------------------
 ;; Includes:
 ;; - vsll.vv/vsra.vv/vsrl.vv
@@ -180,3 +180,52 @@ (define_expand "v<optab><mode>3"
                                NULL_RTX, <VM>mode);
   DONE;
 })
+
+;; =========================================================================
+;; == Unary arithmetic
+;; =========================================================================
+
+;; 
-------------------------------------------------------------------------------
+;; ---- [INT] Unary operations
+;; 
-------------------------------------------------------------------------------
+;; Includes:
+;; - vneg.v/vnot.v
+;; 
-------------------------------------------------------------------------------
+(define_expand "<optab><mode>2"
+  [(set (match_operand:VI 0 "register_operand")
+    (any_int_unop:VI
+     (match_operand:VI 1 "register_operand")))]
+  "TARGET_VECTOR"
+{
+  riscv_vector::emit_len_op (code_for_pred (<CODE>, <MODE>mode),
+                            operands[0], operands[1], NULL_RTX, <VM>mode);
+  DONE;
+})
+
+;; 
-------------------------------------------------------------------------------
+;; - ABS expansion to vmslt and vneg
+;; 
-------------------------------------------------------------------------------
+
+(define_expand "abs<mode>2"
+  [(set (match_operand:VI 0 "register_operand")
+    (match_operand:VI 1 "register_operand"))]
+  "TARGET_VECTOR"
+{
+  // Create a zero constant.
+  rtx zero = gen_const_vec_duplicate (<MODE>mode, GEN_INT (0));
+
+  // Compare the source vector against it.
+  rtx ltcmp = gen_rtx_LT (<VM>mode, operands[1], zero);
+
+  // Mask out all non-negative elements.
+  rtx mask = gen_reg_rtx (<VM>mode);
+  riscv_vector::emit_len_cmp (code_for_pred_ltge (<MODE>mode),
+                             mask, ltcmp, operands[1], zero,
+                             NULL_RTX, <VM>mode);
+
+  // Emit a masked vneg, negating only the negative elements.
+  riscv_vector::emit_masked_len_op (code_for_pred (NEG, <MODE>mode),
+                                   mask, operands[0], operands[1],
+                                   NULL_RTX, <VM>mode);
+  DONE;
+})
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 12634d0ac1a..7c588086fa0 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -171,6 +171,8 @@ void emit_vlmax_reg_op (unsigned, rtx, rtx, rtx, 
machine_mode);
 void emit_len_op (unsigned, rtx, rtx, rtx, machine_mode);
 void emit_len_binop (unsigned, rtx, rtx, rtx, rtx, machine_mode,
                     machine_mode = VOIDmode);
+void emit_masked_len_op (unsigned, rtx, rtx, rtx, rtx, machine_mode);
+void emit_len_cmp (unsigned, rtx, rtx, rtx, rtx, rtx, machine_mode);
 enum vlmul_type get_vlmul (machine_mode);
 unsigned int get_ratio (machine_mode);
 unsigned int get_nf (machine_mode);
@@ -181,6 +183,7 @@ int get_avl_type (rtx);
 unsigned int calculate_ratio (unsigned int, enum vlmul_type);
 enum tail_policy
 {
+  TAIL_UNDEFINED = -1,
   TAIL_UNDISTURBED = 0,
   TAIL_AGNOSTIC = 1,
   TAIL_ANY = 2,
@@ -188,12 +191,13 @@ enum tail_policy
 
 enum mask_policy
 {
+  MASK_UNDEFINED = -1,
   MASK_UNDISTURBED = 0,
   MASK_AGNOSTIC = 1,
   MASK_ANY = 2,
 };
-enum tail_policy get_prefer_tail_policy ();
-enum mask_policy get_prefer_mask_policy ();
+enum tail_policy get_preferred_tail_policy ();
+enum mask_policy get_preferred_mask_policy ();
 rtx get_avl_type_rtx (enum avl_type);
 opt_machine_mode get_vector_mode (scalar_mode, poly_uint64);
 opt_machine_mode get_tuple_mode (machine_mode, unsigned int);
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index d65e7300303..64ad3970267 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -54,11 +54,11 @@ namespace riscv_vector {
 static bool
 const_vlmax_p (machine_mode mode)
 {
-  poly_uint64 nuints = GET_MODE_NUNITS (mode);
+  poly_uint64 nunits = GET_MODE_NUNITS (mode);
 
-  return nuints.is_constant ()
+  return nunits.is_constant ()
     /* The vsetivli can only hold register 0~31.  */
-    ? (IN_RANGE (nuints.to_constant (), 0, 31))
+    ? (IN_RANGE (nunits.to_constant (), 0, 31))
     /* Only allowed in VLS-VLMAX mode.  */
     : false;
 }
@@ -66,38 +66,68 @@ const_vlmax_p (machine_mode mode)
 template <int MAX_OPERANDS> class insn_expander
 {
 public:
-  insn_expander () : m_opno (0), has_dest(false) {}
+  insn_expander () : m_opno (0), has_dest (false) {}
+
   void add_output_operand (rtx x, machine_mode mode)
   {
     create_output_operand (&m_ops[m_opno++], x, mode);
     gcc_assert (m_opno <= MAX_OPERANDS);
   }
+
+  void add_source_operand (rtx x, machine_mode mode)
+    {
+      add_src (x);
+      add_input_operand (x, mode);
+    }
+
   void add_input_operand (rtx x, machine_mode mode)
   {
     create_input_operand (&m_ops[m_opno++], x, mode);
     gcc_assert (m_opno <= MAX_OPERANDS);
   }
+
   void add_all_one_mask_operand (machine_mode mode)
   {
     add_input_operand (CONSTM1_RTX (mode), mode);
   }
+
   void add_vundef_operand (machine_mode mode)
   {
     add_input_operand (RVV_VUNDEF (mode), mode);
   }
-  void add_policy_operand (enum tail_policy vta, enum mask_policy vma)
+
+  void add_policy_operands (enum tail_policy vta = TAIL_UNDEFINED,
+                           enum mask_policy vma = MASK_UNDEFINED)
   {
-    rtx tail_policy_rtx = gen_int_mode (vta, Pmode);
-    rtx mask_policy_rtx = gen_int_mode (vma, Pmode);
-    add_input_operand (tail_policy_rtx, Pmode);
-    add_input_operand (mask_policy_rtx, Pmode);
+    /* If no policies were specified, use the default ones.  */
+    if (vta == TAIL_UNDEFINED)
+      vta = get_preferred_tail_policy ();
+    if (vma == MASK_UNDEFINED)
+      vma = get_preferred_mask_policy ();
+
+    /* RVV Spec 3.4.3.
+       Mask destination tail elements are always treated as tail-agnostic,
+       regardless of the setting of vta.  */
+    if (!is_mask_destination_instruction ())
+      {
+       rtx tail_policy_rtx = gen_int_mode (vta, Pmode);
+       add_input_operand (tail_policy_rtx, Pmode);
+      }
+
+    /* RVV Spec 15.1.
+       Vector mask logical instructions are always unmasked.  */
+    if (!is_mask_logical_instruction ())
+      {
+       rtx mask_policy_rtx = gen_int_mode (vma, Pmode);
+       add_input_operand (mask_policy_rtx, Pmode);
+      }
   }
   void add_avl_type_operand (avl_type type)
   {
     add_input_operand (gen_int_mode (type, Pmode), Pmode);
   }
 
-  void set_dest_and_mask (rtx mask, rtx dest, machine_mode mask_mode)
+  void set_dest_and_mask (rtx dest, rtx mask, machine_mode mask_mode)
   {
     dest_mode = GET_MODE (dest);
     has_dest = true;
@@ -133,8 +163,7 @@ public:
 
       add_input_operand (len, Pmode);
 
-      if (GET_MODE_CLASS (dest_mode) != MODE_VECTOR_BOOL)
-       add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy 
());
+      add_policy_operands ();
 
       add_avl_type_operand (vlmax_p ? avl_type::VLMAX : avl_type::NONVLMAX);
     }
@@ -150,9 +179,36 @@ public:
       expand_insn (icode, m_opno, m_ops);
   }
 
+  bool is_mask_destination_instruction ()
+    {
+      gcc_assert (has_dest);
+      return (GET_MODE_CLASS (dest_mode) == MODE_VECTOR_BOOL);
+    }
+
+  bool is_mask_logical_instruction ()
+    {
+      if (!is_mask_destination_instruction ())
+       return false;
+
+      if (!srcs.length ())
+       return false;
+
+      for (rtx src : srcs)
+       if (GET_MODE_CLASS (GET_MODE (src)) != MODE_VECTOR_BOOL)
+         return false;
+
+      return true;
+    }
+
+  void add_src (rtx src)
+    {
+      srcs.quick_push (src);
+    }
+
 private:
   int m_opno;
   bool has_dest;
+  auto_vec<rtx, 3> srcs;
   machine_mode dest_mode;
   expand_operand m_ops[MAX_OPERANDS];
 };
@@ -252,9 +308,9 @@ emit_pred_op (unsigned icode, rtx mask, rtx dest, rtx src, 
rtx len,
              machine_mode mask_mode, bool force_vlmax = false)
 {
   insn_expander<8> e;
-  e.set_dest_and_mask (mask, dest, mask_mode);
+  e.set_dest_and_mask (dest, mask, mask_mode);
 
-  e.add_input_operand (src, GET_MODE (src));
+  e.add_source_operand (src, GET_MODE (src));
 
   e.set_len_and_policy (len, force_vlmax);
 
@@ -269,20 +325,40 @@ emit_pred_binop (unsigned icode, rtx mask, rtx dest, rtx 
src1, rtx src2,
                 machine_mode scalar_mode = VOIDmode)
 {
   insn_expander<9> e;
-  e.set_dest_and_mask (mask, dest, mask_mode);
+  e.set_dest_and_mask (dest, mask, mask_mode);
 
   gcc_assert (VECTOR_MODE_P (GET_MODE (src1))
              || VECTOR_MODE_P (GET_MODE (src2)));
 
   if (VECTOR_MODE_P (GET_MODE (src1)))
-    e.add_input_operand (src1, GET_MODE (src1));
+    e.add_source_operand (src1, GET_MODE (src1));
   else
-    e.add_input_operand (src1, scalar_mode);
+    e.add_source_operand (src1, scalar_mode);
 
   if (VECTOR_MODE_P (GET_MODE (src2)))
-    e.add_input_operand (src2, GET_MODE (src2));
+    e.add_source_operand (src2, GET_MODE (src2));
   else
-    e.add_input_operand (src2, scalar_mode);
+    e.add_source_operand (src2, scalar_mode);
+
+  e.set_len_and_policy (len);
+
+  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src1) || MEM_P 
(src2));
+}
+
+/* Emit an RVV comparison.  */
+static void
+emit_pred_cmp (unsigned icode, rtx mask, rtx dest, rtx cmp,
+              rtx src1, rtx src2,
+              rtx len, machine_mode mask_mode)
+{
+  insn_expander<9> e;
+
+  e.set_dest_and_mask (dest, mask, mask_mode);
+
+  e.add_input_operand (cmp, GET_MODE (cmp));
+
+  e.add_source_operand (src1, GET_MODE (src1));
+  e.add_source_operand (src2, GET_MODE (src2));
 
   e.set_len_and_policy (len);
 
@@ -332,6 +408,8 @@ emit_vlmax_reg_op (unsigned icode, rtx dest, rtx src, rtx 
len,
                /* Force VLMAX */ true);
 }
 
+/* Emit a binary operation with sources SRC1 and SRC2 and a given length
+   LEN.  */
 void
 emit_len_binop (unsigned icode, rtx dest, rtx src1, rtx src2, rtx len,
                machine_mode mask_mode, machine_mode scalar_mode)
@@ -340,13 +418,29 @@ emit_len_binop (unsigned icode, rtx dest, rtx src1, rtx 
src2, rtx len,
                   mask_mode, scalar_mode);
 }
 
+/* Emit a masked operation with a given length LEN.  */
+void
+emit_masked_len_op (unsigned icode, rtx mask, rtx dest, rtx src, rtx len,
+                   machine_mode mask_mode)
+{
+  emit_pred_op (icode, mask, dest, src, len, mask_mode);
+}
+
+/* Emit an unmasked comparison whose result is stored in the mask DEST.  */
+void
+emit_len_cmp (unsigned icode, rtx dest, rtx op, rtx src1, rtx src2,
+             rtx len, machine_mode mask_mode)
+{
+  emit_pred_cmp (icode, NULL_RTX, dest, op, src1, src2, len, mask_mode);
+}
+
 /* Emit vid.v instruction.  */
 
 static void
 emit_index_op (rtx dest, machine_mode mask_mode)
 {
   insn_expander<7> e;
-  e.set_dest_and_mask (NULL, dest, mask_mode);
+  e.set_dest_and_mask (dest, NULL, mask_mode);
 
   e.set_len_and_policy (NULL, true);
 
@@ -621,9 +715,9 @@ get_ma (rtx ma)
   return INTVAL (ma);
 }
 
-/* Get prefer tail policy.  */
+/* Get preferred tail policy.  */
 enum tail_policy
-get_prefer_tail_policy ()
+get_preferred_tail_policy ()
 {
   /* TODO: By default, we choose to use TAIL_ANY which allows
      compiler pick up either agnostic or undisturbed. Maybe we
@@ -632,9 +726,9 @@ get_prefer_tail_policy ()
   return TAIL_ANY;
 }
 
-/* Get prefer mask policy.  */
+/* Get preferred mask policy.  */
 enum mask_policy
-get_prefer_mask_policy ()
+get_preferred_mask_policy ()
 {
   /* TODO: By default, we choose to use MASK_ANY which allows
      compiler pick up either agnostic or undisturbed. Maybe we
@@ -935,8 +1029,8 @@ slide1_sew64_helper (int unspec, machine_mode mode, 
machine_mode demote_mode,
     }
 
   rtx temp = gen_reg_rtx (demote_mode);
-  rtx ta = gen_int_mode (get_prefer_tail_policy (), Pmode);
-  rtx ma = gen_int_mode (get_prefer_mask_policy (), Pmode);
+  rtx ta = gen_int_mode (get_preferred_tail_policy (), Pmode);
+  rtx ma = gen_int_mode (get_preferred_mask_policy (), Pmode);
   rtx merge = RVV_VUNDEF (demote_mode);
   /* Handle vslide1<ud>_tu.  */
   if (register_operand (ops[2], mode)
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc 
b/gcc/config/riscv/riscv-vector-builtins.cc
index dd714bfcee2..0487827e65e 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -2743,7 +2743,7 @@ get_tail_policy_for_pred (enum predication_type_index 
pred)
 {
   if (pred == PRED_TYPE_tu || pred == PRED_TYPE_tum || pred == PRED_TYPE_tumu)
     return gen_int_mode (TAIL_UNDISTURBED, Pmode);
-  return gen_int_mode (get_prefer_tail_policy (), Pmode);
+  return gen_int_mode (get_preferred_tail_policy (), Pmode);
 }
 
 /* Get MASK policy for predication. If predication indicates MU, return the MU.
@@ -2753,7 +2753,7 @@ get_mask_policy_for_pred (enum predication_type_index 
pred)
 {
   if (pred == PRED_TYPE_tumu || pred == PRED_TYPE_mu)
     return gen_int_mode (MASK_UNDISTURBED, Pmode);
-  return gen_int_mode (get_prefer_mask_policy (), Pmode);
+  return gen_int_mode (get_preferred_mask_policy (), Pmode);
 }
 
 tree
diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index 9847d649d1d..0ecd0bfa2ea 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -566,8 +566,8 @@ get_default_ta ()
 {
   /* For the instruction that doesn't require TA, we still need a default value
      to emit vsetvl. We pick up the default value according to prefer policy. 
*/
-  return (bool) (get_prefer_tail_policy () & 0x1
-                || (get_prefer_tail_policy () >> 1 & 0x1));
+  return (bool) (get_preferred_tail_policy () & 0x1
+                || (get_preferred_tail_policy () >> 1 & 0x1));
 }
 
 /* Get default mask policy.  */
@@ -576,8 +576,8 @@ get_default_ma ()
 {
   /* For the instruction that doesn't require MA, we still need a default value
      to emit vsetvl. We pick up the default value according to prefer policy. 
*/
-  return (bool) (get_prefer_mask_policy () & 0x1
-                || (get_prefer_mask_policy () >> 1 & 0x1));
+  return (bool) (get_preferred_mask_policy () & 0x1
+                || (get_preferred_mask_policy () >> 1 & 0x1));
 }
 
 /* Helper function to get TA operand.  */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-run.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-run.c
new file mode 100644
index 00000000000..d6aaa785055
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-run.c
@@ -0,0 +1,29 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model 
--param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "abs-template.h"
+
+#include <assert.h>
+
+#define SZ 255
+
+#define RUN(TYPE)                              \
+  TYPE a##TYPE[SZ];                            \
+  for (int i = 0; i < SZ; i++)                 \
+  {                                            \
+    a##TYPE[i] = i - 127;                      \
+  }                                            \
+  vabs_##TYPE (a##TYPE, a##TYPE, SZ);          \
+  for (int i = 0; i < SZ; i++)                 \
+    assert (a##TYPE[i] == abs (i - 127));       \
+
+#define RUN_ALL()                              \
+ RUN(int8_t)                                   \
+ RUN(int16_t)                                  \
+ RUN(int32_t)                                  \
+ RUN(int64_t)
+
+int main ()
+{
+  RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-rv32gcv.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-rv32gcv.c
new file mode 100644
index 00000000000..cbe0ba0b0ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-rv32gcv.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv 
-mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "abs-template.h"
+
+/* { dg-final { scan-assembler-times {\tvmslt\.vi} 4 } } */
+/* { dg-final { scan-assembler-times {\tvneg\.v} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-rv64gcv.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-rv64gcv.c
new file mode 100644
index 00000000000..c0c52176a42
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-rv64gcv.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv 
-mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "abs-template.h"
+
+/* { dg-final { scan-assembler-times {\tvmslt\.vi} 4 } } */
+/* { dg-final { scan-assembler-times {\tvneg\.v} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-template.h 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-template.h
new file mode 100644
index 00000000000..a54238c8ff2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/abs-template.h
@@ -0,0 +1,26 @@
+#include <stdlib.h>
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE)                                \
+  __attribute__((noipa))                               \
+  void vabs_##TYPE (TYPE *dst, TYPE *a, int n) \
+  {                                                    \
+    for (int i = 0; i < n; i++)                                \
+      dst[i] = abs (a[i]);                             \
+  }
+
+#define TEST_TYPE2(TYPE)                               \
+  __attribute__((noipa))                               \
+  void vabs_##TYPE (TYPE *dst, TYPE *a, int n) \
+  {                                                    \
+    for (int i = 0; i < n; i++)                                \
+      dst[i] = llabs (a[i]);                           \
+  }
+
+#define TEST_ALL()     \
+ TEST_TYPE(int8_t)     \
+ TEST_TYPE(int16_t)    \
+ TEST_TYPE(int32_t)    \
+ TEST_TYPE2(int64_t)
+
+TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-run.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-run.c
new file mode 100644
index 00000000000..abeb50f21ea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-run.c
@@ -0,0 +1,29 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model 
--param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "vneg-template.h"
+
+#include <assert.h>
+
+#define SZ 255
+
+#define RUN(TYPE)                              \
+  TYPE a##TYPE[SZ];                            \
+  for (int i = 0; i < SZ; i++)                 \
+  {                                            \
+    a##TYPE[i] = i - 127;                      \
+  }                                            \
+  vneg_##TYPE (a##TYPE, a##TYPE, SZ);  \
+  for (int i = 0; i < SZ; i++)                 \
+    assert (a##TYPE[i] == -(i - 127));
+
+#define RUN_ALL()                              \
+ RUN(int8_t)                                   \
+ RUN(int16_t)                                  \
+ RUN(int32_t)                                  \
+ RUN(int64_t)
+
+int main ()
+{
+  RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-rv32gcv.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-rv32gcv.c
new file mode 100644
index 00000000000..69d9ebb0953
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-rv32gcv.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv 
-mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "vneg-template.h"
+
+/* { dg-final { scan-assembler-times {\tvneg\.v} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-rv64gcv.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-rv64gcv.c
new file mode 100644
index 00000000000..d2c2e17c13e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-rv64gcv.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv 
-mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "vneg-template.h"
+
+/* { dg-final { scan-assembler-times {\tvneg\.v} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-template.h 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-template.h
new file mode 100644
index 00000000000..72701fceb8c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vneg-template.h
@@ -0,0 +1,17 @@
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE)                                \
+  __attribute__((noipa))                               \
+  void vneg_##TYPE (TYPE *dst, TYPE *a, int n)         \
+  {                                                    \
+    for (int i = 0; i < n; i++)                                \
+      dst[i] =  -a[i];                                 \
+  }
+
+#define TEST_ALL()     \
+ TEST_TYPE(int8_t)     \
+ TEST_TYPE(int16_t)    \
+ TEST_TYPE(int32_t)    \
+ TEST_TYPE(int64_t)
+
+TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-run.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-run.c
new file mode 100644
index 00000000000..1c6836742cf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_vector } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model 
--param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "vnot-template.h"
+
+#include <assert.h>
+
+#define SZ 255
+
+#define RUN(TYPE)                              \
+  TYPE a##TYPE[SZ];                            \
+  for (int i = 0; i < SZ; i++)                 \
+  {                                            \
+    a##TYPE[i] = i - 127;                      \
+  }                                            \
+  vnot_##TYPE (a##TYPE, a##TYPE, SZ);          \
+  for (int i = 0; i < SZ; i++)                 \
+    assert (a##TYPE[i] == (TYPE)~(i - 127));
+
+#define RUN_ALL()                              \
+ RUN(int8_t)                                   \
+ RUN(int16_t)                                  \
+ RUN(int32_t)                                  \
+ RUN(int64_t)                                  \
+ RUN(uint8_t)                                  \
+ RUN(uint16_t)                                 \
+ RUN(uint32_t)                                 \
+ RUN(uint64_t)
+
+int main ()
+{
+  RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-rv32gcv.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-rv32gcv.c
new file mode 100644
index 00000000000..ecc4316bd4f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-rv32gcv.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv 
-mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "vnot-template.h"
+
+/* { dg-final { scan-assembler-times {\tvnot\.v} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-rv64gcv.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-rv64gcv.c
new file mode 100644
index 00000000000..67e28af2cd8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-rv64gcv.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv 
-mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "vnot-template.h"
+
+/* { dg-final { scan-assembler-times {\tvnot\.v} 8 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-template.h 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-template.h
new file mode 100644
index 00000000000..19c78d6e49b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/vnot-template.h
@@ -0,0 +1,21 @@
+#include <stdint-gcc.h>
+
+#define TEST_TYPE(TYPE)                                \
+  __attribute__((noipa))                               \
+  void vnot_##TYPE (TYPE *dst, TYPE *a, int n)         \
+  {                                                    \
+    for (int i = 0; i < n; i++)                                \
+      dst[i] =  ~a[i];                                 \
+  }
+
+#define TEST_ALL()     \
+ TEST_TYPE(int8_t)     \
+ TEST_TYPE(uint8_t)    \
+ TEST_TYPE(int16_t)    \
+ TEST_TYPE(uint16_t)   \
+ TEST_TYPE(int32_t)    \
+ TEST_TYPE(uint32_t)   \
+ TEST_TYPE(int64_t)    \
+ TEST_TYPE(uint64_t)
+
+TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp 
b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
index bc99cc0c3cf..54e35cb6c62 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
+++ b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp
@@ -63,6 +63,8 @@ foreach op $AUTOVEC_TEST_OPTS {
     "" "$op"
   dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/binop/*.\[cS\]]] 
\
     "" "$op"
+  dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/unop/*.\[cS\]]] \
+    "" "$op"
 }
 
 # VLS-VLMAX tests
-- 
2.40.1

Reply via email to