public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v3 0/6] RISC-V: autovec: Add auto-vectorization support
@ 2023-03-08  3:27 Michael Collison
  2023-03-08  3:27 ` [PATCH v3 1/6] RISC-V: autovec: Add new predicates and function prototypes Michael Collison
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Michael Collison @ 2023-03-08  3:27 UTC (permalink / raw)
  To: gcc-patches

This series of patches adds foundational support for RISC-V auto-vectorization support. These patches are based on the current upstream rvv vector intrinsic support and is not a new implementation. Most of the implementation consists of adding the new vector cost model, the autovectorization patterns themselves and target hooks. This implementation only provides support for integer addition and subtraction as a proof of concept. This patch set should not be construed to be feature complete. Based on conversations with the community these patches are intended to lay the groundwork for feature completion and collaboration within the RISC-V community.

These patches are largely based off the work of Juzhe Zhong (juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>) of RiVAI. More specifically the rvv-next branch at: https://github.com/riscv-collab/riscv-gcc.git <https://github.com/riscv-collab/riscv-gcc.git>is the foundation of this patch set. 

As discussed on this list, if these patches are approved they will be merged into a "auto-vectorization" branch once gcc-13 branches for release. There are two known issues related to crashes (assert failures) associated with tree vectorization; one of which I have sent a patch for and have received feedback. 

Changes in v3:

- Removed the cost model and cost hooks based on feedback from Richard Biener
- Used RVV_VUNDEF macro to fix failing patterns

Changes in v2 

- Updated ChangeLog entry to include RiVAI contributions 
- Fixed ChangeLog email formatting 
- Fixed gnu formatting issues in the code 

Michael Collison (6):
  RISC-V: Add new predicates and function prototypes
  RISC-V: autovec: Export policy functions to global scope
  RISC-V:autovec: Add auto-vectorization support functions
  RISC-V:autovec: Add target vectorization hooks
  RISC-V:autovec: Add autovectorization patterns for add & sub
  RISC-V:autovec: Add autovectorization tests for add & sub

 gcc/config/riscv/predicates.md                |  13 ++
 gcc/config/riscv/riscv-opts.h                 |  40 ++++
 gcc/config/riscv/riscv-protos.h               |  15 ++
 gcc/config/riscv/riscv-v.cc                   | 178 +++++++++++++++++-
 gcc/config/riscv/riscv-vector-builtins.cc     |   4 +-
 gcc/config/riscv/riscv-vector-builtins.h      |   2 +
 gcc/config/riscv/riscv.cc                     | 156 +++++++++++++++
 gcc/config/riscv/riscv.md                     |   1 +
 gcc/config/riscv/riscv.opt                    |  20 ++
 gcc/config/riscv/vector-auto.md               | 172 +++++++++++++++++
 gcc/config/riscv/vector-iterators.md          |   2 +
 gcc/config/riscv/vector.md                    |   4 +-
 .../riscv/rvv/autovec/loop-add-rv32.c         |  24 +++
 .../gcc.target/riscv/rvv/autovec/loop-add.c   |  24 +++
 .../riscv/rvv/autovec/loop-sub-rv32.c         |  24 +++
 .../gcc.target/riscv/rvv/autovec/loop-sub.c   |  24 +++
 16 files changed, 698 insertions(+), 5 deletions(-)
 create mode 100644 gcc/config/riscv/vector-auto.md
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-add-rv32.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-add.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-sub-rv32.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-sub.c

-- 
2.34.1


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

* [PATCH v3 1/6] RISC-V: autovec: Add new predicates and function prototypes
  2023-03-08  3:27 [PATCH v3 0/6] RISC-V: autovec: Add auto-vectorization support Michael Collison
@ 2023-03-08  3:27 ` Michael Collison
  2023-03-08  3:27 ` [PATCH v3 2/6] RISC-V: autovec: Export policy functions to global scope Michael Collison
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Collison @ 2023-03-08  3:27 UTC (permalink / raw)
  To: gcc-patches

2023-03-02  Michael Collison  <collison@rivosinc.com>
	    Juzhe Zhong  <juzhe.zhong@rivai.ai>

	* config/riscv/riscv-protos.h (riscv_classify_vlmul_field):
	New external declaration.
	(riscv_vector_preferred_simd_mode): Ditto.
	(riscv_tuple_mode_p): Ditto.
	(riscv_vector_mask_mode_p): Ditto.
	(riscv_classify_nf): Ditto.
	(riscv_vlmul_regsize): Ditto.
	(riscv_vector_preferred_simd_mode): Ditto.
	(riscv_vector_get_mask_mode): Ditto.
	(emit_vlmax_vsetvl): Ditto.
	(get_mask_policy_no_pred): Ditto.
	(get_tail_policy_no_pred): Ditto.
	* config/riscv/riscv-opts.h (riscv_vector_bits_enum): New enum.
	(riscv_vector_lmul_enum): Ditto.
	(vlmul_field_enum): Ditto.
	* config/riscv/riscv-v.cc (emit_vlmax_vsetvl):
	Remove static scope.
	* config/riscv/riscv.opt (riscv_vector_lmul):
	New option -mriscv_vector_lmul.
	* config/riscv/predicates.md (p_reg_or_const_csr_operand):
	New predicate.
	(vector_reg_or_const_dup_operand): Ditto.
---
 gcc/config/riscv/predicates.md  | 13 +++++++++++
 gcc/config/riscv/riscv-opts.h   | 40 +++++++++++++++++++++++++++++++++
 gcc/config/riscv/riscv-protos.h | 15 +++++++++++++
 gcc/config/riscv/riscv-v.cc     |  2 +-
 gcc/config/riscv/riscv.opt      | 20 +++++++++++++++++
 5 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index 0d9d7701c7e..19aa5e12920 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -264,6 +264,14 @@
 })
 
 ;; Predicates for the V extension.
+(define_special_predicate "p_reg_or_const_csr_operand"
+  (match_code "reg, subreg, const_int")
+{
+  if (CONST_INT_P (op))
+    return satisfies_constraint_K (op);
+  return GET_MODE (op) == Pmode;
+})
+
 (define_special_predicate "vector_length_operand"
   (ior (match_operand 0 "pmode_register_operand")
        (match_operand 0 "const_csr_operand")))
@@ -291,6 +299,11 @@
   (and (match_code "const_vector")
        (match_test "rtx_equal_p (op, riscv_vector::gen_scalar_move_mask (GET_MODE (op)))")))
 
+(define_predicate "vector_reg_or_const_dup_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_test "const_vec_duplicate_p (op)
+       && !CONST_POLY_INT_P (CONST_VECTOR_ELT (op, 0))")))
+
 (define_predicate "vector_mask_operand"
   (ior (match_operand 0 "register_operand")
        (match_operand 0 "vector_all_trues_mask_operand")))
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index ff398c0a2ae..c6b6d84fce4 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -67,6 +67,46 @@ enum stack_protector_guard {
   SSP_GLOBAL			/* global canary */
 };
 
+/* RVV vector register sizes.  */
+enum riscv_vector_bits_enum
+{
+  RVV_SCALABLE,
+  RVV_NOT_IMPLEMENTED = RVV_SCALABLE,
+  RVV_64 = 64,
+  RVV_128 = 128,
+  RVV_256 = 256,
+  RVV_512 = 512,
+  RVV_1024 = 1024,
+  RVV_2048 = 2048,
+  RVV_4096 = 4096,
+  RVV_8192 = 8192,
+  RVV_16384 = 16384,
+  RVV_32768 = 32768,
+  RVV_65536 = 65536
+};
+
+/* vectorization factor.  */
+enum riscv_vector_lmul_enum
+{
+  RVV_LMUL1 = 1,
+  RVV_LMUL2 = 2,
+  RVV_LMUL4 = 4,
+  RVV_LMUL8 = 8
+};
+
+enum vlmul_field_enum
+{
+  VLMUL_FIELD_000, /* LMUL = 1.  */
+  VLMUL_FIELD_001, /* LMUL = 2.  */
+  VLMUL_FIELD_010, /* LMUL = 4.  */
+  VLMUL_FIELD_011, /* LMUL = 8.  */
+  VLMUL_FIELD_100, /* RESERVED.  */
+  VLMUL_FIELD_101, /* LMUL = 1/8.  */
+  VLMUL_FIELD_110, /* LMUL = 1/4.  */
+  VLMUL_FIELD_111, /* LMUL = 1/2.  */
+  MAX_VLMUL_FIELD
+};
+
 #define MASK_ZICSR    (1 << 0)
 #define MASK_ZIFENCEI (1 << 1)
 
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 88a6bf5442f..6a486a1cd61 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -217,4 +217,19 @@ const unsigned int RISCV_BUILTIN_SHIFT = 1;
 /* Mask that selects the riscv_builtin_class part of a function code.  */
 const unsigned int RISCV_BUILTIN_CLASS = (1 << RISCV_BUILTIN_SHIFT) - 1;
 
+/* Routines implemented in riscv-v.cc.  */
+
+namespace riscv_vector {
+extern unsigned int riscv_classify_vlmul_field (enum machine_mode m);
+extern machine_mode riscv_vector_preferred_simd_mode (scalar_mode mode,
+						      unsigned vf);
+extern bool riscv_tuple_mode_p (machine_mode);
+extern bool riscv_vector_mask_mode_p (machine_mode);
+extern int riscv_classify_nf (machine_mode);
+extern int riscv_vlmul_regsize (machine_mode);
+extern opt_machine_mode riscv_vector_get_mask_mode (machine_mode mode);
+extern rtx emit_vlmax_vsetvl (machine_mode vmode);
+extern rtx get_mask_policy_no_pred ();
+extern rtx get_tail_policy_no_pred ();
+}
 #endif /* ! GCC_RISCV_PROTOS_H */
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index d65c65b26cd..2d2de6e4a6c 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -109,7 +109,7 @@ const_vec_all_same_in_range_p (rtx x, HOST_WIDE_INT minval,
 	  && IN_RANGE (INTVAL (elt), minval, maxval));
 }
 
-static rtx
+rtx
 emit_vlmax_vsetvl (machine_mode vmode)
 {
   rtx vl = gen_reg_rtx (Pmode);
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 95535235354..27005fb0f4a 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -70,6 +70,26 @@ Enum(abi_type) String(lp64f) Value(ABI_LP64F)
 EnumValue
 Enum(abi_type) String(lp64d) Value(ABI_LP64D)
 
+Enum
+Name(riscv_vector_lmul) Type(enum riscv_vector_lmul_enum)
+The possible vectorization factor:
+
+EnumValue
+Enum(riscv_vector_lmul) String(1) Value(RVV_LMUL1)
+
+EnumValue
+Enum(riscv_vector_lmul) String(2) Value(RVV_LMUL2)
+
+EnumValue
+Enum(riscv_vector_lmul) String(4) Value(RVV_LMUL4)
+
+EnumValue
+Enum(riscv_vector_lmul) String(8) Value(RVV_LMUL8)
+
+mriscv-vector-lmul=
+Target RejectNegative Joined Enum(riscv_vector_lmul) Var(riscv_vector_lmul) Init(RVV_LMUL1)
+-mriscv-vector-lmul=<lmul>	Set the vf using lmul in auto-vectorization.
+
 mfdiv
 Target Mask(FDIV)
 Use hardware floating-point divide and square root instructions.
-- 
2.34.1


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

* [PATCH v3 2/6] RISC-V: autovec: Export policy functions to global scope
  2023-03-08  3:27 [PATCH v3 0/6] RISC-V: autovec: Add auto-vectorization support Michael Collison
  2023-03-08  3:27 ` [PATCH v3 1/6] RISC-V: autovec: Add new predicates and function prototypes Michael Collison
@ 2023-03-08  3:27 ` Michael Collison
  2023-03-08  3:27 ` [PATCH v3 3/6] RISC-V: autovec: Add auto-vectorization support functions Michael Collison
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Collison @ 2023-03-08  3:27 UTC (permalink / raw)
  To: gcc-patches

2023-03-02  Michael Collison  <collison@rivosinc.com>
	    Juzhe Zhong  <juzhe.zhong@rivai.ai>

	* config/riscv/riscv-vector-builtins.cc (get_tail_policy_for_pred):
	Remove static declaration to to make externally visible.
	(get_mask_policy_for_pred): Ditto.
	* config/riscv/riscv-vector-builtins.h (get_tail_policy_for_pred):
	New external declaration.
	(get_mask_policy_for_pred): Ditto.
---
 gcc/config/riscv/riscv-vector-builtins.cc | 4 ++--
 gcc/config/riscv/riscv-vector-builtins.h  | 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 2d57086262b..352ffd8867d 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -2448,7 +2448,7 @@ use_real_merge_p (enum predication_type_index pred)
 
 /* Get TAIL policy for predication. If predication indicates TU, return the TU.
    Otherwise, return the prefer default configuration.  */
-static rtx
+rtx
 get_tail_policy_for_pred (enum predication_type_index pred)
 {
   if (pred == PRED_TYPE_tu || pred == PRED_TYPE_tum || pred == PRED_TYPE_tumu)
@@ -2458,7 +2458,7 @@ get_tail_policy_for_pred (enum predication_type_index pred)
 
 /* Get MASK policy for predication. If predication indicates MU, return the MU.
    Otherwise, return the prefer default configuration.  */
-static rtx
+rtx
 get_mask_policy_for_pred (enum predication_type_index pred)
 {
   if (pred == PRED_TYPE_tumu || pred == PRED_TYPE_mu)
diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
index 8464aa9b7e9..d62d2bdab54 100644
--- a/gcc/config/riscv/riscv-vector-builtins.h
+++ b/gcc/config/riscv/riscv-vector-builtins.h
@@ -456,6 +456,8 @@ extern const char *const operand_suffixes[NUM_OP_TYPES];
 extern const rvv_builtin_suffixes type_suffixes[NUM_VECTOR_TYPES + 1];
 extern const char *const predication_suffixes[NUM_PRED_TYPES];
 extern rvv_builtin_types_t builtin_types[NUM_VECTOR_TYPES + 1];
+extern rtx get_tail_policy_for_pred (enum predication_type_index pred);
+extern rtx get_mask_policy_for_pred (enum predication_type_index pred);
 
 inline tree
 rvv_arg_type_info::get_scalar_type (vector_type_index type_idx) const
-- 
2.34.1


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

* [PATCH v3 3/6] RISC-V: autovec: Add auto-vectorization support functions
  2023-03-08  3:27 [PATCH v3 0/6] RISC-V: autovec: Add auto-vectorization support Michael Collison
  2023-03-08  3:27 ` [PATCH v3 1/6] RISC-V: autovec: Add new predicates and function prototypes Michael Collison
  2023-03-08  3:27 ` [PATCH v3 2/6] RISC-V: autovec: Export policy functions to global scope Michael Collison
@ 2023-03-08  3:27 ` Michael Collison
  2023-03-08  3:27 ` [PATCH v3 4/6] RISC-V: autovec: Add target vectorization hooks Michael Collison
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Collison @ 2023-03-08  3:27 UTC (permalink / raw)
  To: gcc-patches

2023-03-02  Michael Collison  <collison@rivosinc.com>
	    Juzhe Zhong  <juzhe.zhong@rivai.ai>

	* config/riscv/riscv-v.cc (riscv_classify_vlmul_field):
	New function.
	(riscv_vector_preferred_simd_mode): Ditto.
	(get_mask_policy_no_pred): Ditto.
	(get_tail_policy_no_pred): Ditto.
	(riscv_tuple_mode_p): Ditto.
	(riscv_classify_nf): Ditto.
	(riscv_vlmul_regsize): Ditto.
	(riscv_vector_mask_mode_p): Ditto.
	(riscv_vector_get_mask_mode): Ditto.
---
 gcc/config/riscv/riscv-v.cc | 176 ++++++++++++++++++++++++++++++++++++
 1 file changed, 176 insertions(+)

diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 2d2de6e4a6c..d21bde1bda6 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -39,9 +39,11 @@
 #include "emit-rtl.h"
 #include "tm_p.h"
 #include "target.h"
+#include "targhooks.h"
 #include "expr.h"
 #include "optabs.h"
 #include "tm-constrs.h"
+#include "riscv-vector-builtins.h"
 #include "rtx-vector-builder.h"
 
 using namespace riscv_vector;
@@ -109,6 +111,41 @@ const_vec_all_same_in_range_p (rtx x, HOST_WIDE_INT minval,
 	  && IN_RANGE (INTVAL (elt), minval, maxval));
 }
 
+/* Return the vlmul field for a specific machine mode.  */
+unsigned int
+riscv_classify_vlmul_field (enum machine_mode mode)
+{
+  /* Make the decision based on the mode's enum value rather than its
+     properties, so that we keep the correct classification regardless
+     of -mriscv-vector-bits.  */
+  switch (mode)
+    {
+    case E_VNx8BImode:
+      return VLMUL_FIELD_111;
+
+    case E_VNx4BImode:
+      return VLMUL_FIELD_110;
+
+    case E_VNx2BImode:
+      return VLMUL_FIELD_101;
+
+    case E_VNx16BImode:
+      return VLMUL_FIELD_000;
+
+    case E_VNx32BImode:
+      return VLMUL_FIELD_001;
+
+    case E_VNx64BImode:
+      return VLMUL_FIELD_010;
+
+    default:
+      break;
+    }
+
+  /* we don't care about VLMUL for Mask.  */
+  return VLMUL_FIELD_000;
+}
+
 rtx
 emit_vlmax_vsetvl (machine_mode vmode)
 {
@@ -163,6 +200,64 @@ calculate_ratio (unsigned int sew, enum vlmul_type vlmul)
   return ratio;
 }
 
+/* Implement TARGET_VECTORIZE_PREFERRED_SIMD_MODE for RVV.  */
+
+machine_mode
+riscv_vector_preferred_simd_mode (scalar_mode mode, unsigned vf)
+{
+  if (!TARGET_VECTOR)
+    return word_mode;
+
+  switch (mode)
+    {
+    case E_QImode:
+      return vf == 1   ? VNx8QImode
+	     : vf == 2 ? VNx16QImode
+	     : vf == 4 ? VNx32QImode
+		       : VNx64QImode;
+      break;
+    case E_HImode:
+      return vf == 1   ? VNx4HImode
+	     : vf == 2 ? VNx8HImode
+	     : vf == 4 ? VNx16HImode
+		       : VNx32HImode;
+      break;
+    case E_SImode:
+      return vf == 1   ? VNx2SImode
+	     : vf == 2 ? VNx4SImode
+	     : vf == 4 ? VNx8SImode
+		       : VNx16SImode;
+      break;
+    case E_DImode:
+      if (riscv_vector_elen_flags != MASK_VECTOR_ELEN_32
+	  && riscv_vector_elen_flags != MASK_VECTOR_ELEN_FP_32)
+	return vf == 1	 ? VNx1DImode
+	       : vf == 2 ? VNx2DImode
+	       : vf == 4 ? VNx4DImode
+			 : VNx8DImode;
+      break;
+    case E_SFmode:
+      if (TARGET_HARD_FLOAT && riscv_vector_elen_flags != MASK_VECTOR_ELEN_32
+	  && riscv_vector_elen_flags != MASK_VECTOR_ELEN_64)
+	return vf == 1	 ? VNx2SFmode
+	       : vf == 2 ? VNx4SFmode
+	       : vf == 4 ? VNx8SFmode
+			 : VNx16SFmode;
+      break;
+    case E_DFmode:
+      if (TARGET_DOUBLE_FLOAT && TARGET_VECTOR_ELEN_FP_64)
+	return vf == 1	 ? VNx1DFmode
+	       : vf == 2 ? VNx2DFmode
+	       : vf == 4 ? VNx4DFmode
+			 : VNx8DFmode;
+      break;
+    default:
+      break;
+    }
+
+  return word_mode;
+}
+
 /* Emit an RVV unmask && vl mov from SRC to DEST.  */
 static void
 emit_pred_op (unsigned icode, rtx mask, rtx dest, rtx src, rtx len,
@@ -375,6 +470,87 @@ get_avl_type_rtx (enum avl_type type)
   return gen_int_mode (type, Pmode);
 }
 
+rtx
+get_mask_policy_no_pred ()
+{
+  return get_mask_policy_for_pred (PRED_TYPE_none);
+}
+
+rtx
+get_tail_policy_no_pred ()
+{
+  return get_mask_policy_for_pred (PRED_TYPE_none);
+}
+
+/* Return true if it is a RVV tuple mode.  */
+bool
+riscv_tuple_mode_p (machine_mode mode ATTRIBUTE_UNUSED)
+{
+  return false;
+}
+
+/* Return nf for a machine mode.  */
+int
+riscv_classify_nf (machine_mode mode)
+{
+  switch (mode)
+    {
+
+    default:
+      break;
+    }
+
+  return 1;
+}
+
+/* Return vlmul register size for a machine mode.  */
+int
+riscv_vlmul_regsize (machine_mode mode)
+{
+  if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
+    return 1;
+  switch (riscv_classify_vlmul_field (mode))
+    {
+    case VLMUL_FIELD_001:
+      return 2;
+    case VLMUL_FIELD_010:
+      return 4;
+    case VLMUL_FIELD_011:
+      return 8;
+    case VLMUL_FIELD_100:
+      gcc_unreachable ();
+    default:
+      return 1;
+    }
+}
+
+/* Return true if it is a RVV mask mode.  */
+bool
+riscv_vector_mask_mode_p (machine_mode mode)
+{
+  return (mode == VNx1BImode || mode == VNx2BImode || mode == VNx4BImode
+	  || mode == VNx8BImode || mode == VNx16BImode || mode == VNx32BImode
+	  || mode == VNx64BImode);
+}
+
+/* Implement TARGET_VECTORIZE_GET_MASK_MODE for RVV.  */
+
+opt_machine_mode
+riscv_vector_get_mask_mode (machine_mode mode)
+{
+  machine_mode mask_mode;
+  int nf = 1;
+  if (riscv_tuple_mode_p (mode))
+    nf = riscv_classify_nf (mode);
+
+  FOR_EACH_MODE_IN_CLASS (mask_mode, MODE_VECTOR_BOOL)
+  if (GET_MODE_INNER (mask_mode) == BImode
+      && known_eq (GET_MODE_NUNITS (mask_mode) * nf, GET_MODE_NUNITS (mode))
+      && riscv_vector_mask_mode_p (mask_mode))
+    return mask_mode;
+  return default_get_mask_mode (mode);
+}
+
 /* Return the RVV vector mode that has NUNITS elements of mode INNER_MODE.
    This function is not only used by builtins, but also will be used by
    auto-vectorization in the future.  */
-- 
2.34.1


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

* [PATCH v3 4/6] RISC-V: autovec: Add target vectorization hooks
  2023-03-08  3:27 [PATCH v3 0/6] RISC-V: autovec: Add auto-vectorization support Michael Collison
                   ` (2 preceding siblings ...)
  2023-03-08  3:27 ` [PATCH v3 3/6] RISC-V: autovec: Add auto-vectorization support functions Michael Collison
@ 2023-03-08  3:27 ` Michael Collison
  2023-03-08  3:27 ` [PATCH v3 5/6] RISC-V: autovec: Add autovectorization patterns for add & sub Michael Collison
  2023-03-08  3:27 ` [PATCH v3 6/6] RISC-V: autovec: Add autovectorization tests " Michael Collison
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Collison @ 2023-03-08  3:27 UTC (permalink / raw)
  To: gcc-patches

2023-03-02  Michael Collison  <collison@rivosinc.com>
	    Juzhe Zhong  <juzhe.zhong@rivai.ai>

	* config/riscv/riscv.cc (riscv_option_override):
	Set riscv_vectorization_factor.
	(riscv_estimated_poly_value): Implement
	TARGET_ESTIMATED_POLY_VALUE.
	(riscv_preferred_simd_mode): Implement
	TARGET_VECTORIZE_PREFERRED_SIMD_MODE.
	(riscv_autovectorize_vector_modes): Implement
	TARGET_AUTOVECTORIZE_VECTOR_MODES.
	(riscv_get_mask_mode): Implement TARGET_VECTORIZE_GET_MASK_MODE.
	(riscv_empty_mask_is_expensive): Implement
	TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE.
	(riscv_vectorize_create_costs): Implement
	TARGET_VECTORIZE_CREATE_COSTS.
	(TARGET_ESTIMATED_POLY_VALUE): Register target macro.
	(TARGET_VECTORIZE_PREFERRED_SIMD_MODE): Ditto.
	(TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES): Ditto.
	(TARGET_VECTORIZE_GET_MASK_MODE): Ditto.
	(TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE): Ditto.
	(TARGET_VECTORIZE_LOOP_LEN_OVERRIDE_MASK): Ditto.
---
 gcc/config/riscv/riscv.cc | 156 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 156 insertions(+)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index befb9b498b7..1ca9f3c7ae4 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -60,6 +60,15 @@ along with GCC; see the file COPYING3.  If not see
 #include "opts.h"
 #include "tm-constrs.h"
 #include "rtl-iter.h"
+#include "gimple.h"
+#include "cfghooks.h"
+#include "cfgloop.h"
+#include "cfgrtl.h"
+#include "sel-sched.h"
+#include "fold-const.h"
+#include "gimple-iterator.h"
+#include "gimple-expr.h"
+#include "tree-vectorizer.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -275,6 +284,9 @@ poly_uint16 riscv_vector_chunks;
 /* The number of bytes in a vector chunk.  */
 unsigned riscv_bytes_per_vector_chunk;
 
+/* Prefer vf for auto-vectorizer.  */
+unsigned riscv_vectorization_factor;
+
 /* Index R is the smallest register class that contains register R.  */
 const enum reg_class riscv_regno_to_class[FIRST_PSEUDO_REGISTER] = {
   GR_REGS,	GR_REGS,	GR_REGS,	GR_REGS,
@@ -6199,6 +6211,10 @@ riscv_option_override (void)
 
   /* Convert -march to a chunks count.  */
   riscv_vector_chunks = riscv_convert_vector_bits ();
+
+  if (TARGET_VECTOR)
+    riscv_vectorization_factor = riscv_vector_lmul;
+
 }
 
 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE.  */
@@ -6893,6 +6909,128 @@ riscv_dwarf_poly_indeterminate_value (unsigned int i, unsigned int *factor,
   return RISCV_DWARF_VLENB;
 }
 
+/* Implement TARGET_ESTIMATED_POLY_VALUE.
+   Look into the tuning structure for an estimate.
+   KIND specifies the type of requested estimate: min, max or likely.
+   For cores with a known RVV width all three estimates are the same.
+   For generic RVV tuning we want to distinguish the maximum estimate from
+   the minimum and likely ones.
+   The likely estimate is the same as the minimum in that case to give a
+   conservative behavior of auto-vectorizing with RVV when it is a win
+   even for 128-bit RVV.
+   When RVV width information is available VAL.coeffs[1] is multiplied by
+   the number of VQ chunks over the initial Advanced SIMD 128 bits.  */
+
+static HOST_WIDE_INT
+riscv_estimated_poly_value (poly_int64 val,
+			    poly_value_estimate_kind kind = POLY_VALUE_LIKELY)
+{
+  unsigned int width_source = BITS_PER_RISCV_VECTOR.is_constant ()
+    ? (unsigned int) BITS_PER_RISCV_VECTOR.to_constant ()
+    : (unsigned int) RVV_SCALABLE;
+
+  /* If there is no core-specific information then the minimum and likely
+     values are based on 128-bit vectors and the maximum is based on
+     the architectural maximum of 2048 bits.  */
+  if (width_source == RVV_SCALABLE)
+    switch (kind)
+      {
+      case POLY_VALUE_MIN:
+      case POLY_VALUE_LIKELY:
+	return val.coeffs[0];
+
+      case POLY_VALUE_MAX:
+	return val.coeffs[0] + val.coeffs[1] * 15;
+      }
+
+  /* Allow BITS_PER_RISCV_VECTOR to be a bitmask of different VL, treating the
+     lowest as likely.  This could be made more general if future -mtune
+     options need it to be.  */
+  if (kind == POLY_VALUE_MAX)
+    width_source = 1 << floor_log2 (width_source);
+  else
+    width_source = least_bit_hwi (width_source);
+
+  /* If the core provides width information, use that.  */
+  HOST_WIDE_INT over_128 = width_source - 128;
+  return val.coeffs[0] + val.coeffs[1] * over_128 / 128;
+}
+
+/* Implement TARGET_VECTORIZE_PREFERRED_SIMD_MODE.  */
+
+static machine_mode
+riscv_preferred_simd_mode (scalar_mode mode)
+{
+  machine_mode vmode =
+    riscv_vector::riscv_vector_preferred_simd_mode (mode,
+						    riscv_vectorization_factor);
+  if (VECTOR_MODE_P (vmode))
+    return vmode;
+
+  return word_mode;
+}
+
+/* Implement TARGET_AUTOVECTORIZE_VECTOR_MODES for RVV.  */
+static unsigned int
+riscv_autovectorize_vector_modes (vector_modes *modes, bool)
+{
+  if (!TARGET_VECTOR)
+    return 0;
+
+  if (riscv_vectorization_factor == RVV_LMUL1)
+    {
+      modes->safe_push (VNx16QImode);
+      modes->safe_push (VNx8QImode);
+      modes->safe_push (VNx4QImode);
+      modes->safe_push (VNx2QImode);
+    }
+  else if (riscv_vectorization_factor == RVV_LMUL2)
+    {
+      modes->safe_push (VNx32QImode);
+      modes->safe_push (VNx16QImode);
+      modes->safe_push (VNx8QImode);
+      modes->safe_push (VNx4QImode);
+    }
+  else if (riscv_vectorization_factor == RVV_LMUL4)
+    {
+      modes->safe_push (VNx64QImode);
+      modes->safe_push (VNx32QImode);
+      modes->safe_push (VNx16QImode);
+      modes->safe_push (VNx8QImode);
+    }
+  else
+    {
+      modes->safe_push (VNx64QImode);
+      modes->safe_push (VNx32QImode);
+      modes->safe_push (VNx16QImode);
+    }
+
+  return 0;
+}
+
+/* Implement TARGET_VECTORIZE_GET_MASK_MODE.  */
+
+static opt_machine_mode
+riscv_get_mask_mode (machine_mode mode)
+{
+  machine_mode mask_mode = VOIDmode;
+  if (TARGET_VECTOR
+      && riscv_vector::riscv_vector_get_mask_mode (mode).exists (&mask_mode))
+    return mask_mode;
+
+  return default_get_mask_mode (mode);
+}
+
+/* Implement TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE.  Assume for now that
+   it isn't worth branching around empty masked ops (including masked
+   stores).  */
+
+static bool
+riscv_empty_mask_is_expensive (unsigned)
+{
+  return false;
+}
+
 /* Return true if a shift-amount matches the trailing cleared bits on
    a bitmask.  */
 
@@ -7144,6 +7282,24 @@ riscv_shamt_matches_mask_p (int shamt, HOST_WIDE_INT mask)
 #undef TARGET_VERIFY_TYPE_CONTEXT
 #define TARGET_VERIFY_TYPE_CONTEXT riscv_verify_type_context
 
+#undef TARGET_ESTIMATED_POLY_VALUE
+#define TARGET_ESTIMATED_POLY_VALUE riscv_estimated_poly_value
+
+#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
+#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE riscv_preferred_simd_mode
+
+#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
+#define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES riscv_autovectorize_vector_modes
+
+#undef TARGET_VECTORIZE_GET_MASK_MODE
+#define TARGET_VECTORIZE_GET_MASK_MODE riscv_get_mask_mode
+
+#undef TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE
+#define TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE riscv_empty_mask_is_expensive
+
+#undef TARGET_VECTORIZE_LOOP_LEN_OVERRIDE_MASK
+#define TARGET_VECTORIZE_LOOP_LEN_OVERRIDE_MASK riscv_loop_len_override_mask
+
 #undef TARGET_VECTOR_ALIGNMENT
 #define TARGET_VECTOR_ALIGNMENT riscv_vector_alignment
 
-- 
2.34.1


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

* [PATCH v3 5/6] RISC-V: autovec: Add autovectorization patterns for add & sub
  2023-03-08  3:27 [PATCH v3 0/6] RISC-V: autovec: Add auto-vectorization support Michael Collison
                   ` (3 preceding siblings ...)
  2023-03-08  3:27 ` [PATCH v3 4/6] RISC-V: autovec: Add target vectorization hooks Michael Collison
@ 2023-03-08  3:27 ` Michael Collison
  2023-03-08  3:27 ` [PATCH v3 6/6] RISC-V: autovec: Add autovectorization tests " Michael Collison
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Collison @ 2023-03-08  3:27 UTC (permalink / raw)
  To: gcc-patches

2023-03-02  Michael Collison  <collison@rivosinc.com>
	    Juzhe Zhong  <juzhe.zhong@rivai.ai>

	* config/riscv/riscv.md (riscv_vector_preferred_simd_mode): Include
	vector-iterators.md.
	* config/riscv/vector-auto.md: New file containing
	autovectorization patterns.
	* config/riscv/vector-iterators.md (UNSPEC_VADD/UNSPEC_VSUB):
	New unspecs for autovectorization patterns.
	* config/riscv/vector.md: Remove include of vector-iterators.md
	and include vector-auto.md.
---
 gcc/config/riscv/riscv.md            |   1 +
 gcc/config/riscv/vector-auto.md      | 172 +++++++++++++++++++++++++++
 gcc/config/riscv/vector-iterators.md |   2 +
 gcc/config/riscv/vector.md           |   4 +-
 4 files changed, 177 insertions(+), 2 deletions(-)
 create mode 100644 gcc/config/riscv/vector-auto.md

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 6c3176042fb..a504ace72e5 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -131,6 +131,7 @@
 (include "predicates.md")
 (include "constraints.md")
 (include "iterators.md")
+(include "vector-iterators.md")
 
 ;; ....................
 ;;
diff --git a/gcc/config/riscv/vector-auto.md b/gcc/config/riscv/vector-auto.md
new file mode 100644
index 00000000000..5227a73d96d
--- /dev/null
+++ b/gcc/config/riscv/vector-auto.md
@@ -0,0 +1,172 @@
+;; Machine description for RISC-V 'V' Extension for GNU compiler.
+;; Copyright (C) 2022-2023 Free Software Foundation, Inc.
+;; Contributed by Juzhe Zhong (juzhe.zhong@rivai.ai), RiVAI Technologies Ltd.
+;; Contributed by Michael Collison (collison@rivosinc.com, Rivos Inc.
+
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] Addition
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vadd.vv
+;; - vadd.vx
+;; - vadd.vi
+;; -------------------------------------------------------------------------
+
+(define_expand "add<mode>3"
+  [(match_operand:VI 0 "register_operand")
+   (match_operand:VI 1 "register_operand")
+   (match_operand:VI 2 "vector_arith_operand")]
+  "TARGET_VECTOR"
+{
+  using namespace riscv_vector;
+
+  rtx merge = RVV_VUNDEF (<MODE>mode);
+  rtx vl = emit_vlmax_vsetvl (<MODE>mode);
+  rtx mask_policy = get_mask_policy_no_pred();
+  rtx tail_policy = get_tail_policy_no_pred();
+  rtx mask = CONSTM1_RTX(<VM>mode);
+  rtx vlmax_avl_p = get_avl_type_rtx(NONVLMAX);
+
+  emit_insn(gen_pred_add<mode>(operands[0], mask, merge, operands[1], operands[2],
+				vl, tail_policy, mask_policy, vlmax_avl_p));
+
+  DONE;
+})
+
+(define_expand "cond_add<mode>"
+  [(match_operand:VI 0 "register_operand")
+   (match_operand:<VM> 1 "register_operand")
+   (match_operand:VI 2 "register_operand")
+   (match_operand:VI 3 "vector_reg_or_const_dup_operand")
+   (match_operand:VI 4 "register_operand")]
+  "TARGET_VECTOR"
+{
+  using namespace riscv_vector;
+
+  rtx merge = operands[4];
+  rtx vl = emit_vlmax_vsetvl (<MODE>mode);
+  rtx mask_policy = get_mask_policy_no_pred();
+  rtx tail_policy = get_tail_policy_no_pred();
+  rtx mask = operands[1];
+  rtx vlmax_avl_p = get_avl_type_rtx(NONVLMAX);
+
+  emit_insn(gen_pred_add<mode>(operands[0], mask, merge, operands[2], operands[3],
+				vl, tail_policy, mask_policy, vlmax_avl_p));
+  DONE;
+})
+
+(define_expand "len_add<mode>"
+  [(match_operand:VI 0 "register_operand")
+   (match_operand:VI 1 "register_operand")
+   (match_operand:VI 2 "vector_reg_or_const_dup_operand")
+   (match_operand 3 "p_reg_or_const_csr_operand")]
+  "TARGET_VECTOR"
+{
+  using namespace riscv_vector;
+
+  rtx merge = RVV_VUNDEF (<MODE>mode);
+  rtx vl = operands[3];
+  rtx mask_policy = get_mask_policy_no_pred();
+  rtx tail_policy = get_tail_policy_no_pred();
+  rtx mask = CONSTM1_RTX(<VM>mode);
+  rtx vlmax_avl_p = get_avl_type_rtx(NONVLMAX);
+
+  emit_insn(gen_pred_add<mode>(operands[0], mask, merge, operands[1], operands[2],
+				vl, tail_policy, mask_policy, vlmax_avl_p));
+  DONE;
+})
+
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] Subtraction
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vsub.vv
+;; - vsub.vx
+;; - vadd.vi
+;; - vrsub.vx
+;; - vrsub.vi
+;; -------------------------------------------------------------------------
+
+(define_expand "sub<mode>3"
+  [(match_operand:VI 0 "register_operand")
+   (match_operand:VI 1 "register_operand")
+   (match_operand:VI 2 "register_operand")]
+  "TARGET_VECTOR"
+{
+  using namespace riscv_vector;
+
+  rtx merge = RVV_VUNDEF (<MODE>mode);
+  rtx vl = emit_vlmax_vsetvl (<MODE>mode);
+  rtx mask_policy = get_mask_policy_no_pred();
+  rtx tail_policy = get_tail_policy_no_pred();
+  rtx mask = CONSTM1_RTX(<VM>mode);
+  rtx vlmax_avl_p = get_avl_type_rtx(NONVLMAX);
+
+  emit_insn(gen_pred_sub<mode>(operands[0], mask, merge, operands[1], operands[2],
+				vl, tail_policy, mask_policy, vlmax_avl_p));
+
+  DONE;
+})
+
+(define_expand "cond_sub<mode>"
+  [(match_operand:VI 0 "register_operand")
+   (match_operand:<VM> 1 "register_operand")
+   (match_operand:VI 2 "register_operand")
+   (match_operand:VI 3 "register_operand")
+   (match_operand:VI 4 "register_operand")]
+  "TARGET_VECTOR"
+{
+  using namespace riscv_vector;
+
+  rtx merge = operands[4];
+  rtx vl = emit_vlmax_vsetvl (<MODE>mode);
+  rtx mask_policy = get_mask_policy_no_pred();
+  rtx tail_policy = get_tail_policy_no_pred();
+  rtx mask = operands[1];
+  rtx vlmax_avl_p = get_avl_type_rtx(NONVLMAX);
+
+  emit_insn(gen_pred_sub<mode>(operands[0], mask, merge, operands[2], operands[3],
+				vl, tail_policy, mask_policy, vlmax_avl_p));
+
+  DONE;
+})
+
+(define_expand "len_sub<mode>"
+  [(match_operand:VI 0 "register_operand")
+   (match_operand:VI 1 "register_operand")
+   (match_operand:VI 2 "register_operand")
+   (match_operand 3 "p_reg_or_const_csr_operand")]
+  "TARGET_VECTOR"
+{
+  using namespace riscv_vector;
+
+  rtx merge = RVV_VUNDEF (<MODE>mode);
+  rtx vl = operands[3];
+  rtx mask_policy = get_mask_policy_no_pred();
+  rtx tail_policy = get_tail_policy_no_pred();
+  rtx mask = CONSTM1_RTX(<VM>mode);
+  rtx vlmax_avl_p = get_avl_type_rtx(NONVLMAX);
+
+  emit_insn(gen_pred_sub<mode>(operands[0], mask, merge, operands[1], operands[2],
+				vl, tail_policy, mask_policy, vlmax_avl_p));
+
+  DONE;
+})
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 61e141e7b64..af80143ce90 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -34,6 +34,8 @@
   UNSPEC_VMULHU
   UNSPEC_VMULHSU
 
+  UNSPEC_VADD
+  UNSPEC_VSUB
   UNSPEC_VADC
   UNSPEC_VSBC
   UNSPEC_VMADC
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 2d4eb8bf1cd..85e531c83ef 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -26,8 +26,6 @@
 ;; - Auto-vectorization (TBD)
 ;; - Combine optimization (TBD)
 
-(include "vector-iterators.md")
-
 (define_constants [
    (INVALID_ATTRIBUTE            255)
    (X0_REGNUM                      0)
@@ -350,6 +348,8 @@
 	   (symbol_ref "INTVAL (operands[4])")]
 	(const_int INVALID_ATTRIBUTE)))
 
+(include "vector-auto.md")
+
 ;; -----------------------------------------------------------------
 ;; ---- Miscellaneous Operations
 ;; -----------------------------------------------------------------
-- 
2.34.1


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

* [PATCH v3 6/6] RISC-V: autovec: Add autovectorization tests for add & sub
  2023-03-08  3:27 [PATCH v3 0/6] RISC-V: autovec: Add auto-vectorization support Michael Collison
                   ` (4 preceding siblings ...)
  2023-03-08  3:27 ` [PATCH v3 5/6] RISC-V: autovec: Add autovectorization patterns for add & sub Michael Collison
@ 2023-03-08  3:27 ` Michael Collison
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Collison @ 2023-03-08  3:27 UTC (permalink / raw)
  To: gcc-patches

2023-03-02  Michael Collison  <collison@rivosinc.com>
	    Vineet Gupta <vineetg@rivosinc.com>

	* gcc.target/riscv/rvv/autovec: New directory
	for autovectorization tests.
	* gcc.target/riscv/rvv/autovec/loop-add-rv32.c: New
	test to verify code generation of vector add on rv32.
	* gcc.target/riscv/rvv/autovec/loop-add.c: New
	test to verify code generation of vector add on rv64.
	* gcc.target/riscv/rvv/autovec/loop-sub-rv32.c: New
	test to verify code generation of vector subtract on rv32.
	* gcc.target/riscv/rvv/autovec/loop-sub.c: New
	test to verify code generation of vector subtract on rv64.
---
 .../riscv/rvv/autovec/loop-add-rv32.c         | 24 +++++++++++++++++++
 .../gcc.target/riscv/rvv/autovec/loop-add.c   | 24 +++++++++++++++++++
 .../riscv/rvv/autovec/loop-sub-rv32.c         | 24 +++++++++++++++++++
 .../gcc.target/riscv/rvv/autovec/loop-sub.c   | 24 +++++++++++++++++++
 4 files changed, 96 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-add-rv32.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-add.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-sub-rv32.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-sub.c

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-add-rv32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-add-rv32.c
new file mode 100644
index 00000000000..bdc3b6892e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-add-rv32.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -march=rv32gcv -mabi=ilp32d" } */
+
+#include <stdint.h>
+
+#define TEST_TYPE(TYPE) 				\
+  void vadd_##TYPE (TYPE *dst, TYPE *a, TYPE *b, int n)	\
+  {							\
+    for (int i = 0; i < n; i++)				\
+      dst[i] = a[i] + b[i];				\
+  }
+
+/* *int8_t not autovec currently. */
+#define TEST_ALL()	\
+ 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()
+
+/* { dg-final { scan-assembler-times {\tvadd\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-add.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-add.c
new file mode 100644
index 00000000000..d7f992c7d27
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-add.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -march=rv64gcv -mabi=lp64d" } */
+
+#include <stdint.h>
+
+#define TEST_TYPE(TYPE) 				\
+  void vadd_##TYPE (TYPE *dst, TYPE *a, TYPE *b, int n)	\
+  {							\
+    for (int i = 0; i < n; i++)				\
+      dst[i] = a[i] + b[i];				\
+  }
+
+/* *int8_t not autovec currently. */
+#define TEST_ALL()	\
+ 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()
+
+/* { dg-final { scan-assembler-times {\tvadd\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-sub-rv32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-sub-rv32.c
new file mode 100644
index 00000000000..7d0a40ec539
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-sub-rv32.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -march=rv32gcv -mabi=ilp32d" } */
+
+#include <stdint.h>
+
+#define TEST_TYPE(TYPE) 				\
+  void vadd_##TYPE (TYPE *dst, TYPE *a, TYPE *b, int n)	\
+  {							\
+    for (int i = 0; i < n; i++)				\
+      dst[i] = a[i] - b[i];				\
+  }
+
+/* *int8_t not autovec currently. */
+#define TEST_ALL()	\
+ 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()
+
+/* { dg-final { scan-assembler-times {\tvsub\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-sub.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-sub.c
new file mode 100644
index 00000000000..c8900884f83
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/loop-sub.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -march=rv64gcv -mabi=lp64d" } */
+
+#include <stdint.h>
+
+#define TEST_TYPE(TYPE) 				\
+  void vadd_##TYPE (TYPE *dst, TYPE *a, TYPE *b, int n)	\
+  {							\
+    for (int i = 0; i < n; i++)				\
+      dst[i] = a[i] - b[i];				\
+  }
+
+/* *int8_t not autovec currently. */
+#define TEST_ALL()	\
+ 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()
+
+/* { dg-final { scan-assembler-times {\tvsub\.vv} 6 } } */
-- 
2.34.1


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

end of thread, other threads:[~2023-03-08  3:27 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-08  3:27 [PATCH v3 0/6] RISC-V: autovec: Add auto-vectorization support Michael Collison
2023-03-08  3:27 ` [PATCH v3 1/6] RISC-V: autovec: Add new predicates and function prototypes Michael Collison
2023-03-08  3:27 ` [PATCH v3 2/6] RISC-V: autovec: Export policy functions to global scope Michael Collison
2023-03-08  3:27 ` [PATCH v3 3/6] RISC-V: autovec: Add auto-vectorization support functions Michael Collison
2023-03-08  3:27 ` [PATCH v3 4/6] RISC-V: autovec: Add target vectorization hooks Michael Collison
2023-03-08  3:27 ` [PATCH v3 5/6] RISC-V: autovec: Add autovectorization patterns for add & sub Michael Collison
2023-03-08  3:27 ` [PATCH v3 6/6] RISC-V: autovec: Add autovectorization tests " Michael Collison

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).