public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] riscv: Add vectorized binops and insn_expander helpers.
@ 2023-05-10 15:24 Robin Dapp
  2023-05-10 15:43 ` 钟居哲
  0 siblings, 1 reply; 9+ messages in thread
From: Robin Dapp @ 2023-05-10 15:24 UTC (permalink / raw)
  To: gcc-patches, juzhe.zhong, Kito Cheng, Michael Collison, palmer,
	jeffreyalaw
  Cc: rdapp.gcc

Hi,

this patch adds basic binary integer operations support.  It is based
on Michael Collison's work and makes use of the existing helpers in
riscv-c.cc.  It introduces emit_nonvlmax_binop which, in turn, uses
emit_pred_binop.  Setting the destination as well as the mask and the
length is factored out into separate functions.

There are several things still missing, most notably the scalar variants
(.vx) as well as multiplication variants and more.

Bootstrapped and regtested.

Regards
 Robin

--

gcc/ChangeLog:

	* config/riscv/autovec.md (<optab><mode>3): Add integer binops.
	* config/riscv/riscv-protos.h (emit_nonvlmax_binop): Declare.
	* config/riscv/riscv-v.cc (emit_pred_op): New function.
	(set_expander_dest_and_mask): New function.
	(emit_pred_binop): New function.
	(emit_nonvlmax_binop): New function.
	* config/riscv/vector-iterators.md: Add new code attribute.
---
 gcc/config/riscv/autovec.md          | 33 ++++++++++
 gcc/config/riscv/riscv-protos.h      |  2 +
 gcc/config/riscv/riscv-v.cc          | 98 ++++++++++++++++++++++------
 gcc/config/riscv/vector-iterators.md | 22 +++++++
 4 files changed, 136 insertions(+), 19 deletions(-)

diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index f1c5ff5951b..15f8d007e07 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -58,3 +58,36 @@ (define_expand "movmisalign<mode>"
     DONE;
   }
 )
+
+;; =========================================================================
+;; == Binary integer operations
+;; =========================================================================
+
+(define_expand "<optab><mode>3"
+  [(set (match_operand:VI 0 "register_operand")
+    (any_int_binop:VI
+     (match_operand:VI 1 "<binop_rhs1_predicate>")
+     (match_operand:VI 2 "<binop_rhs2_predicate>")))]
+  "TARGET_VECTOR"
+{
+  if (!register_operand (operands[2], <MODE>mode))
+    {
+      rtx cst;
+      gcc_assert (const_vec_duplicate_p(operands[2], &cst));
+      machine_mode inner = <VEL>mode;
+      machine_mode op2mode = Pmode;
+      if (inner == E_QImode || inner == E_HImode || inner == E_SImode)
+	op2mode = inner;
+
+      riscv_vector::emit_nonvlmax_binop (code_for_pred_scalar
+					 (<BINOP_TO_UPPERCASE>, <MODE>mode),
+					 operands[0], operands[1], cst,
+					 NULL_RTX, <VM>mode, op2mode);
+    }
+  else
+    riscv_vector::emit_nonvlmax_binop (code_for_pred
+				       (<BINOP_TO_UPPERCASE>, <MODE>mode),
+				       operands[0], operands[1], operands[2],
+				       NULL_RTX, <VM>mode);
+  DONE;
+})
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index c0293a306f9..75cdb90b9c9 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -169,6 +169,8 @@ void emit_hard_vlmax_vsetvl (machine_mode, rtx);
 void emit_vlmax_op (unsigned, rtx, rtx, machine_mode);
 void emit_vlmax_op (unsigned, rtx, rtx, rtx, machine_mode);
 void emit_nonvlmax_op (unsigned, rtx, rtx, rtx, machine_mode);
+void emit_nonvlmax_binop (unsigned, rtx, rtx, rtx, rtx, machine_mode,
+			  machine_mode = VOIDmode);
 enum vlmul_type get_vlmul (machine_mode);
 unsigned int get_ratio (machine_mode);
 unsigned int get_nf (machine_mode);
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 7ca49ca67c1..3c43dfc5eea 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -53,7 +53,7 @@ namespace riscv_vector {
 template <int MAX_OPERANDS> class insn_expander
 {
 public:
-  insn_expander () : m_opno (0) {}
+  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);
@@ -84,6 +84,44 @@ public:
     add_input_operand (gen_int_mode (type, Pmode), Pmode);
   }
 
+  void set_dest_and_mask (rtx mask, rtx dest, machine_mode mask_mode)
+  {
+    dest_mode = GET_MODE (dest);
+    has_dest = true;
+
+    add_output_operand (dest, dest_mode);
+
+    if (mask)
+      add_input_operand (mask, GET_MODE (mask));
+    else
+      add_all_one_mask_operand (mask_mode);
+
+    add_vundef_operand (dest_mode);
+  }
+
+  void set_len_and_policy (rtx len, bool vlmax_p)
+    {
+      gcc_assert (has_dest);
+      gcc_assert (len || vlmax_p);
+
+      if (len)
+	add_input_operand (len, Pmode);
+      else
+	{
+	  rtx vlmax = gen_reg_rtx (Pmode);
+	  emit_vlmax_vsetvl (dest_mode, vlmax);
+	  add_input_operand (vlmax, Pmode);
+	}
+
+      if (GET_MODE_CLASS (dest_mode) != MODE_VECTOR_BOOL)
+	add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
+
+      if (vlmax_p)
+	add_avl_type_operand (avl_type::VLMAX);
+      else
+	add_avl_type_operand (avl_type::NONVLMAX);
+    }
+
   void expand (enum insn_code icode, bool temporary_volatile_p = false)
   {
     if (temporary_volatile_p)
@@ -97,6 +135,8 @@ public:
 
 private:
   int m_opno;
+  bool has_dest;
+  machine_mode dest_mode;
   expand_operand m_ops[MAX_OPERANDS];
 };
 
@@ -190,11 +230,11 @@ autovec_use_vlmax_p (void)
 }
 
 /* Emit an RVV unmask && vl mov from SRC to DEST.  */
+template <int MAX_OPERANDS>
 static void
-emit_pred_op (unsigned icode, rtx mask, rtx dest, rtx src, rtx len,
-	      machine_mode mask_mode, bool vlmax_p)
+set_expander_dest_and_mask (insn_expander<MAX_OPERANDS> &e, rtx mask, rtx dest,
+			    machine_mode mask_mode)
 {
-  insn_expander<8> e;
   machine_mode mode = GET_MODE (dest);
 
   e.add_output_operand (dest, mode);
@@ -205,29 +245,41 @@ emit_pred_op (unsigned icode, rtx mask, rtx dest, rtx src, rtx len,
     e.add_all_one_mask_operand (mask_mode);
 
   e.add_vundef_operand (mode);
+}
 
-  e.add_input_operand (src, GET_MODE (src));
 
-  if (len)
-    e.add_input_operand (len, Pmode);
-  else
-    {
-      rtx vlmax = gen_reg_rtx (Pmode);
-      emit_vlmax_vsetvl (mode, vlmax);
-      e.add_input_operand (vlmax, Pmode);
-    }
+/* 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,
+	      machine_mode mask_mode, bool vlmax_p)
+{
+  insn_expander<8> e;
+  e.set_dest_and_mask (mask, dest, mask_mode);
 
-  if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
-    e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
+  e.add_input_operand (src, GET_MODE (src));
 
-  if (vlmax_p)
-    e.add_avl_type_operand (avl_type::VLMAX);
-  else
-    e.add_avl_type_operand (avl_type::NONVLMAX);
+  e.set_len_and_policy (len, vlmax_p);
 
   e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src));
 }
 
+/* Emit an RVV unmask && vl mov from SRC to DEST.  */
+static void
+emit_pred_binop (unsigned icode, rtx mask, rtx dest, rtx src1, rtx src2,
+		 rtx len, machine_mode mask_mode, machine_mode op2mode,
+		 bool vlmax_p)
+{
+  insn_expander<9> e;
+  e.set_dest_and_mask (mask, dest, mask_mode);
+
+  e.add_input_operand (src1, GET_MODE (src1));
+  e.add_input_operand (src2, op2mode == VOIDmode ? GET_MODE (src2) : op2mode);
+
+  e.set_len_and_policy (len, vlmax_p);
+
+  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src1) || MEM_P (src2));
+}
+
 void
 emit_vlmax_op (unsigned icode, rtx dest, rtx src, machine_mode mask_mode)
 {
@@ -248,6 +300,14 @@ emit_nonvlmax_op (unsigned icode, rtx dest, rtx src, rtx len,
   emit_pred_op (icode, NULL_RTX, dest, src, len, mask_mode, false);
 }
 
+void
+emit_nonvlmax_binop (unsigned icode, rtx dest, rtx src1, rtx src2, rtx len,
+		     machine_mode mask_mode, machine_mode op2mode)
+{
+  emit_pred_binop (icode, NULL_RTX, dest, src1, src2, len, mask_mode, op2mode,
+		   false);
+}
+
 static void
 expand_const_vector (rtx target, rtx src, machine_mode mask_mode)
 {
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 29c9d77674b..42848627c8c 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -1401,6 +1401,26 @@ (define_code_iterator any_int_binop [plus minus and ior xor ashift ashiftrt lshi
   smax umax smin umin mult div udiv mod umod
 ])
 
+(define_code_attr BINOP_TO_UPPERCASE [
+    (plus "PLUS")
+    (minus "MINUS")
+    (and "AND")
+    (ior "IOR")
+    (xor "XOR")
+    (ashift "ASHIFT")
+    (ashiftrt "ASHIFTRT")
+    (lshiftrt "LSHIFTRT")
+    (smax "SMAX")
+    (umax "UMAX")
+    (smin "SMIN")
+    (umin "UMIN")
+    (mult "MULT")
+    (div "DIV")
+    (udiv "UDIV")
+    (mod "MOD")
+    (umod "UMOD")
+])
+
 (define_code_iterator any_int_unop [neg not])
 
 (define_code_iterator any_commutative_binop [plus and ior xor
@@ -1409,6 +1429,8 @@ (define_code_iterator any_commutative_binop [plus and ior xor
 
 (define_code_iterator any_non_commutative_binop [minus div udiv mod umod])
 
+(define_code_iterator any_immediate_binop [plus minus and ior xor])
+
 (define_code_iterator any_sat_int_binop [ss_plus ss_minus us_plus us_minus])
 (define_code_iterator sat_int_plus_binop [ss_plus us_plus])
 (define_code_iterator sat_int_minus_binop [ss_minus us_minus])
-- 
2.40.0

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

* Re: [PATCH] riscv: Add vectorized binops and insn_expander helpers.
  2023-05-10 15:24 [PATCH] riscv: Add vectorized binops and insn_expander helpers Robin Dapp
@ 2023-05-10 15:43 ` 钟居哲
  2023-05-10 18:02   ` Robin Dapp
  0 siblings, 1 reply; 9+ messages in thread
From: 钟居哲 @ 2023-05-10 15:43 UTC (permalink / raw)
  To: rdapp.gcc, gcc-patches, kito.cheng, Michael Collison, palmer, Jeff Law
  Cc: rdapp.gcc

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

Thanks Robin.

A couple comments here:
+      machine_mode op2mode = Pmode;
+      if (inner == E_QImode || inner == E_HImode || inner == E_SImode)
+ op2mode = inner;

Remove it.

+ <BINOP_TO_UPPERCASE> 
change it into <CODE>

+ e.add_input_operand (src2, op2mode == VOIDmode ? GET_MODE (src2) : op2mode);
Very confusing here.

+(define_code_attr BINOP_TO_UPPERCASE [
+    (plus "PLUS")
+    (minus "MINUS")
+    (and "AND")
+    (ior "IOR")
+    (xor "XOR")
+    (ashift "ASHIFT")
+    (ashiftrt "ASHIFTRT")
+    (lshiftrt "LSHIFTRT")
+    (smax "SMAX")
+    (umax "UMAX")
+    (smin "SMIN")
+    (umin "UMIN")
+    (mult "MULT")
+    (div "DIV")
+    (udiv "UDIV")
+    (mod "MOD")
+    (umod "UMOD")
+])

Remove it.

Thanks.


juzhe.zhong@rivai.ai
 
From: Robin Dapp
Date: 2023-05-10 23:24
To: gcc-patches; juzhe.zhong@rivai.ai; Kito Cheng; Michael Collison; palmer; jeffreyalaw
CC: rdapp.gcc
Subject: [PATCH] riscv: Add vectorized binops and insn_expander helpers.
Hi,
 
this patch adds basic binary integer operations support.  It is based
on Michael Collison's work and makes use of the existing helpers in
riscv-c.cc.  It introduces emit_nonvlmax_binop which, in turn, uses
emit_pred_binop.  Setting the destination as well as the mask and the
length is factored out into separate functions.
 
There are several things still missing, most notably the scalar variants
(.vx) as well as multiplication variants and more.
 
Bootstrapped and regtested.
 
Regards
Robin
 
--
 
gcc/ChangeLog:
 
* config/riscv/autovec.md (<optab><mode>3): Add integer binops.
* config/riscv/riscv-protos.h (emit_nonvlmax_binop): Declare.
* config/riscv/riscv-v.cc (emit_pred_op): New function.
(set_expander_dest_and_mask): New function.
(emit_pred_binop): New function.
(emit_nonvlmax_binop): New function.
* config/riscv/vector-iterators.md: Add new code attribute.
---
gcc/config/riscv/autovec.md          | 33 ++++++++++
gcc/config/riscv/riscv-protos.h      |  2 +
gcc/config/riscv/riscv-v.cc          | 98 ++++++++++++++++++++++------
gcc/config/riscv/vector-iterators.md | 22 +++++++
4 files changed, 136 insertions(+), 19 deletions(-)
 
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index f1c5ff5951b..15f8d007e07 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -58,3 +58,36 @@ (define_expand "movmisalign<mode>"
     DONE;
   }
)
+
+;; =========================================================================
+;; == Binary integer operations
+;; =========================================================================
+
+(define_expand "<optab><mode>3"
+  [(set (match_operand:VI 0 "register_operand")
+    (any_int_binop:VI
+     (match_operand:VI 1 "<binop_rhs1_predicate>")
+     (match_operand:VI 2 "<binop_rhs2_predicate>")))]
+  "TARGET_VECTOR"
+{
+  if (!register_operand (operands[2], <MODE>mode))
+    {
+      rtx cst;
+      gcc_assert (const_vec_duplicate_p(operands[2], &cst));
+      machine_mode inner = <VEL>mode;
+      machine_mode op2mode = Pmode;
+      if (inner == E_QImode || inner == E_HImode || inner == E_SImode)
+ op2mode = inner;
+
+      riscv_vector::emit_nonvlmax_binop (code_for_pred_scalar
+ (<BINOP_TO_UPPERCASE>, <MODE>mode),
+ operands[0], operands[1], cst,
+ NULL_RTX, <VM>mode, op2mode);
+    }
+  else
+    riscv_vector::emit_nonvlmax_binop (code_for_pred
+        (<BINOP_TO_UPPERCASE>, <MODE>mode),
+        operands[0], operands[1], operands[2],
+        NULL_RTX, <VM>mode);
+  DONE;
+})
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index c0293a306f9..75cdb90b9c9 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -169,6 +169,8 @@ void emit_hard_vlmax_vsetvl (machine_mode, rtx);
void emit_vlmax_op (unsigned, rtx, rtx, machine_mode);
void emit_vlmax_op (unsigned, rtx, rtx, rtx, machine_mode);
void emit_nonvlmax_op (unsigned, rtx, rtx, rtx, machine_mode);
+void emit_nonvlmax_binop (unsigned, rtx, rtx, rtx, rtx, machine_mode,
+   machine_mode = VOIDmode);
enum vlmul_type get_vlmul (machine_mode);
unsigned int get_ratio (machine_mode);
unsigned int get_nf (machine_mode);
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 7ca49ca67c1..3c43dfc5eea 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -53,7 +53,7 @@ namespace riscv_vector {
template <int MAX_OPERANDS> class insn_expander
{
public:
-  insn_expander () : m_opno (0) {}
+  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);
@@ -84,6 +84,44 @@ public:
     add_input_operand (gen_int_mode (type, Pmode), Pmode);
   }
+  void set_dest_and_mask (rtx mask, rtx dest, machine_mode mask_mode)
+  {
+    dest_mode = GET_MODE (dest);
+    has_dest = true;
+
+    add_output_operand (dest, dest_mode);
+
+    if (mask)
+      add_input_operand (mask, GET_MODE (mask));
+    else
+      add_all_one_mask_operand (mask_mode);
+
+    add_vundef_operand (dest_mode);
+  }
+
+  void set_len_and_policy (rtx len, bool vlmax_p)
+    {
+      gcc_assert (has_dest);
+      gcc_assert (len || vlmax_p);
+
+      if (len)
+ add_input_operand (len, Pmode);
+      else
+ {
+   rtx vlmax = gen_reg_rtx (Pmode);
+   emit_vlmax_vsetvl (dest_mode, vlmax);
+   add_input_operand (vlmax, Pmode);
+ }
+
+      if (GET_MODE_CLASS (dest_mode) != MODE_VECTOR_BOOL)
+ add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
+
+      if (vlmax_p)
+ add_avl_type_operand (avl_type::VLMAX);
+      else
+ add_avl_type_operand (avl_type::NONVLMAX);
+    }
+
   void expand (enum insn_code icode, bool temporary_volatile_p = false)
   {
     if (temporary_volatile_p)
@@ -97,6 +135,8 @@ public:
private:
   int m_opno;
+  bool has_dest;
+  machine_mode dest_mode;
   expand_operand m_ops[MAX_OPERANDS];
};
@@ -190,11 +230,11 @@ autovec_use_vlmax_p (void)
}
/* Emit an RVV unmask && vl mov from SRC to DEST.  */
+template <int MAX_OPERANDS>
static void
-emit_pred_op (unsigned icode, rtx mask, rtx dest, rtx src, rtx len,
-       machine_mode mask_mode, bool vlmax_p)
+set_expander_dest_and_mask (insn_expander<MAX_OPERANDS> &e, rtx mask, rtx dest,
+     machine_mode mask_mode)
{
-  insn_expander<8> e;
   machine_mode mode = GET_MODE (dest);
   e.add_output_operand (dest, mode);
@@ -205,29 +245,41 @@ emit_pred_op (unsigned icode, rtx mask, rtx dest, rtx src, rtx len,
     e.add_all_one_mask_operand (mask_mode);
   e.add_vundef_operand (mode);
+}
-  e.add_input_operand (src, GET_MODE (src));
-  if (len)
-    e.add_input_operand (len, Pmode);
-  else
-    {
-      rtx vlmax = gen_reg_rtx (Pmode);
-      emit_vlmax_vsetvl (mode, vlmax);
-      e.add_input_operand (vlmax, Pmode);
-    }
+/* 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,
+       machine_mode mask_mode, bool vlmax_p)
+{
+  insn_expander<8> e;
+  e.set_dest_and_mask (mask, dest, mask_mode);
-  if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
-    e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
+  e.add_input_operand (src, GET_MODE (src));
-  if (vlmax_p)
-    e.add_avl_type_operand (avl_type::VLMAX);
-  else
-    e.add_avl_type_operand (avl_type::NONVLMAX);
+  e.set_len_and_policy (len, vlmax_p);
   e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src));
}
+/* Emit an RVV unmask && vl mov from SRC to DEST.  */
+static void
+emit_pred_binop (unsigned icode, rtx mask, rtx dest, rtx src1, rtx src2,
+ rtx len, machine_mode mask_mode, machine_mode op2mode,
+ bool vlmax_p)
+{
+  insn_expander<9> e;
+  e.set_dest_and_mask (mask, dest, mask_mode);
+
+  e.add_input_operand (src1, GET_MODE (src1));
+  e.add_input_operand (src2, op2mode == VOIDmode ? GET_MODE (src2) : op2mode);
+
+  e.set_len_and_policy (len, vlmax_p);
+
+  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src1) || MEM_P (src2));
+}
+
void
emit_vlmax_op (unsigned icode, rtx dest, rtx src, machine_mode mask_mode)
{
@@ -248,6 +300,14 @@ emit_nonvlmax_op (unsigned icode, rtx dest, rtx src, rtx len,
   emit_pred_op (icode, NULL_RTX, dest, src, len, mask_mode, false);
}
+void
+emit_nonvlmax_binop (unsigned icode, rtx dest, rtx src1, rtx src2, rtx len,
+      machine_mode mask_mode, machine_mode op2mode)
+{
+  emit_pred_binop (icode, NULL_RTX, dest, src1, src2, len, mask_mode, op2mode,
+    false);
+}
+
static void
expand_const_vector (rtx target, rtx src, machine_mode mask_mode)
{
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 29c9d77674b..42848627c8c 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -1401,6 +1401,26 @@ (define_code_iterator any_int_binop [plus minus and ior xor ashift ashiftrt lshi
   smax umax smin umin mult div udiv mod umod
])
+(define_code_attr BINOP_TO_UPPERCASE [
+    (plus "PLUS")
+    (minus "MINUS")
+    (and "AND")
+    (ior "IOR")
+    (xor "XOR")
+    (ashift "ASHIFT")
+    (ashiftrt "ASHIFTRT")
+    (lshiftrt "LSHIFTRT")
+    (smax "SMAX")
+    (umax "UMAX")
+    (smin "SMIN")
+    (umin "UMIN")
+    (mult "MULT")
+    (div "DIV")
+    (udiv "UDIV")
+    (mod "MOD")
+    (umod "UMOD")
+])
+
(define_code_iterator any_int_unop [neg not])
(define_code_iterator any_commutative_binop [plus and ior xor
@@ -1409,6 +1429,8 @@ (define_code_iterator any_commutative_binop [plus and ior xor
(define_code_iterator any_non_commutative_binop [minus div udiv mod umod])
+(define_code_iterator any_immediate_binop [plus minus and ior xor])
+
(define_code_iterator any_sat_int_binop [ss_plus ss_minus us_plus us_minus])
(define_code_iterator sat_int_plus_binop [ss_plus us_plus])
(define_code_iterator sat_int_minus_binop [ss_minus us_minus])
-- 
2.40.0
 

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

* Re: [PATCH] riscv: Add vectorized binops and insn_expander helpers.
  2023-05-10 15:43 ` 钟居哲
@ 2023-05-10 18:02   ` Robin Dapp
  2023-05-10 22:55     ` 钟居哲
  0 siblings, 1 reply; 9+ messages in thread
From: Robin Dapp @ 2023-05-10 18:02 UTC (permalink / raw)
  To: 钟居哲,
	gcc-patches, kito.cheng, Michael Collison, palmer, Jeff Law

> +      machine_mode op2mode = Pmode;
> +      if (inner == E_QImode || inner == E_HImode || inner == E_SImode)
> + op2mode = inner;

This I added in order to match the scalar variants like

  [(set (match_operand:VI_QHS 0 "register_operand"      "=vd,vd, vr, vr")
	(if_then_else:VI_QHS
	  (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")
	     (reg:SI VL_REGNUM)
	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
	  (any_commutative_binop:VI_QHS
	    (vec_duplicate:VI_QHS
	      (match_operand:<VEL> 4 "reg_or_0_operand"  "rJ,rJ, rJ, rJ"))

Any other way to get there?

> + e.add_input_operand (src2, op2mode == VOIDmode ? GET_MODE (src2) : op2mode);
> Very confusing here.

Hmm I see, the VOIDmode being abused as default might be confusing here.
Would an additional parameter like "bool set_op2_mode" make it clearer?
Another option is to separate this into another function altogether like
emit_len_binop_scalar or so.

> + <BINOP_TO_UPPERCASE> 
> change it into <CODE>

Done and removed the rest.

Thanks.

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

* Re: Re: [PATCH] riscv: Add vectorized binops and insn_expander helpers.
  2023-05-10 18:02   ` Robin Dapp
@ 2023-05-10 22:55     ` 钟居哲
  2023-05-11 10:26       ` [PATCH v2] RISC-V: " Robin Dapp
  0 siblings, 1 reply; 9+ messages in thread
From: 钟居哲 @ 2023-05-10 22:55 UTC (permalink / raw)
  To: rdapp.gcc, gcc-patches, kito.cheng, Michael Collison, palmer, Jeff Law

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

>> This I added in order to match the scalar variants like
 
 >>  [(set (match_operand:VI_QHS 0 "register_operand"      "=vd,vd, vr, vr")
>> (if_then_else:VI_QHS
>>   (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")
 >>     (reg:SI VL_REGNUM)
 >>     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
 >>  (any_commutative_binop:VI_QHS
 >>    (vec_duplicate:VI_QHS
 >>      (match_operand:<VEL> 4 "reg_or_0_operand"  "rJ,rJ, rJ, rJ"))
 
>> Any other way to get there?

No, you don't need to care about that. 
Intrinsic patterns are well designed, you just use "GET_MODE_INNER" which can
well handle that.

 >>     Hmm I see, the VOIDmode being abused as default might be confusing here.
 >>     Would an additional parameter like "bool set_op2_mode" make it clearer?
 >>     Another option is to separate this into another function altogether like
 >>     emit_len_binop_scalar or so.

No, you just use op2mode which you pass through.




juzhe.zhong@rivai.ai
 
From: Robin Dapp
Date: 2023-05-11 02:02
To: 钟居哲; gcc-patches; kito.cheng; Michael Collison; palmer; Jeff Law
Subject: Re: [PATCH] riscv: Add vectorized binops and insn_expander helpers.
> +      machine_mode op2mode = Pmode;
> +      if (inner == E_QImode || inner == E_HImode || inner == E_SImode)
> + op2mode = inner;
 
This I added in order to match the scalar variants like
 
  [(set (match_operand:VI_QHS 0 "register_operand"      "=vd,vd, vr, vr")
(if_then_else:VI_QHS
  (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")
     (reg:SI VL_REGNUM)
     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
  (any_commutative_binop:VI_QHS
    (vec_duplicate:VI_QHS
      (match_operand:<VEL> 4 "reg_or_0_operand"  "rJ,rJ, rJ, rJ"))
 
Any other way to get there?
 
> + e.add_input_operand (src2, op2mode == VOIDmode ? GET_MODE (src2) : op2mode);
> Very confusing here.
 
Hmm I see, the VOIDmode being abused as default might be confusing here.
Would an additional parameter like "bool set_op2_mode" make it clearer?
Another option is to separate this into another function altogether like
emit_len_binop_scalar or so.
 
> + <BINOP_TO_UPPERCASE> 
> change it into <CODE>
 
Done and removed the rest.
 
Thanks.
 

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

* [PATCH v2] RISC-V: Add vectorized binops and insn_expander helpers.
  2023-05-10 22:55     ` 钟居哲
@ 2023-05-11 10:26       ` Robin Dapp
  2023-05-11 10:34         ` juzhe.zhong
  0 siblings, 1 reply; 9+ messages in thread
From: Robin Dapp @ 2023-05-11 10:26 UTC (permalink / raw)
  To: 钟居哲,
	gcc-patches, kito.cheng, Michael Collison, palmer, Jeff Law
  Cc: rdapp.gcc

Changes from v1:

 - Rebase against Juzhe's vec_series patch.
 - Get rid of redundant scalar mode setting.


This patch adds basic binary integer operations support.  It is based
on Michael Collison's work and makes use of the existing helpers in
riscv-c.cc.  It introduces emit_nonvlmax_binop which, in turn, uses
emit_pred_binop.  Setting the destination as well as the mask and the
length are factored out into separate functions.

gcc/ChangeLog:

	* config/riscv/autovec.md (<optab><mode>3): Add integer binops.
	* config/riscv/riscv-protos.h (emit_nonvlmax_binop): Declare.
	* config/riscv/riscv-v.cc (emit_pred_op): New function.
	(set_expander_dest_and_mask): New function.
	(emit_pred_binop): New function.
	(emit_nonvlmax_binop): New function.

Co-authored-by: Michael Collison <collison@rivosinc.com>
---
 gcc/config/riscv/autovec.md     |  37 ++++++++
 gcc/config/riscv/riscv-protos.h |   2 +
 gcc/config/riscv/riscv-v.cc     | 148 ++++++++++++++++++--------------
 3 files changed, 123 insertions(+), 64 deletions(-)

diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 99dc4f046b0..e249f4be704 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -82,3 +82,40 @@ (define_expand "@vec_series<mode>"
     DONE;
   }
 )
+
+;; ========================================================================
+;; == Vector operations
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] Binary operations
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vadd.vv/vsub.vv/...
+;; - vadd.vi/vsub.vi/...
+;; -------------------------------------------------------------------------
+
+(define_expand "<optab><mode>3"
+  [(set (match_operand:VI 0 "register_operand")
+    (any_int_binop:VI
+     (match_operand:VI 1 "<binop_rhs1_predicate>")
+     (match_operand:VI 2 "<binop_rhs2_predicate>")))]
+  "TARGET_VECTOR"
+{
+  if (!register_operand (operands[2], <MODE>mode))
+    {
+      rtx cst;
+      gcc_assert (const_vec_duplicate_p(operands[2], &cst));
+      riscv_vector::emit_nonvlmax_binop (code_for_pred_scalar
+					 (<CODE>, <MODE>mode),
+					 operands[0], operands[1], cst,
+					 NULL, <VM>mode,
+					 <VEL>mode);
+    }
+  else
+    riscv_vector::emit_nonvlmax_binop (code_for_pred
+				       (<CODE>, <MODE>mode),
+				       operands[0], operands[1], operands[2],
+				       NULL, <VM>mode);
+  DONE;
+})
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index e8a728ae226..4d0589e502c 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -169,6 +169,8 @@ void emit_hard_vlmax_vsetvl (machine_mode, rtx);
 void emit_vlmax_op (unsigned, rtx, rtx, machine_mode);
 void emit_vlmax_op (unsigned, rtx, rtx, rtx, machine_mode);
 void emit_nonvlmax_op (unsigned, rtx, rtx, rtx, machine_mode);
+void emit_nonvlmax_binop (unsigned, rtx, rtx, rtx, rtx, machine_mode,
+			  machine_mode = VOIDmode);
 enum vlmul_type get_vlmul (machine_mode);
 unsigned int get_ratio (machine_mode);
 unsigned int get_nf (machine_mode);
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 381e6601a17..8f46226d571 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -53,7 +53,7 @@ namespace riscv_vector {
 template <int MAX_OPERANDS> class insn_expander
 {
 public:
-  insn_expander () : m_opno (0) {}
+  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);
@@ -84,6 +84,44 @@ public:
     add_input_operand (gen_int_mode (type, Pmode), Pmode);
   }
 
+  void set_dest_and_mask (rtx mask, rtx dest, machine_mode mask_mode)
+  {
+    dest_mode = GET_MODE (dest);
+    has_dest = true;
+
+    add_output_operand (dest, dest_mode);
+
+    if (mask)
+      add_input_operand (mask, GET_MODE (mask));
+    else
+      add_all_one_mask_operand (mask_mode);
+
+    add_vundef_operand (dest_mode);
+  }
+
+  void set_len_and_policy (rtx len, bool vlmax_p)
+    {
+      gcc_assert (has_dest);
+      gcc_assert (len || vlmax_p);
+
+      if (len)
+	add_input_operand (len, Pmode);
+      else
+	{
+	  rtx vlmax = gen_reg_rtx (Pmode);
+	  emit_vlmax_vsetvl (dest_mode, vlmax);
+	  add_input_operand (vlmax, Pmode);
+	}
+
+      if (GET_MODE_CLASS (dest_mode) != MODE_VECTOR_BOOL)
+	add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
+
+      if (vlmax_p)
+	add_avl_type_operand (avl_type::VLMAX);
+      else
+	add_avl_type_operand (avl_type::NONVLMAX);
+    }
+
   void expand (enum insn_code icode, bool temporary_volatile_p = false)
   {
     if (temporary_volatile_p)
@@ -97,6 +135,8 @@ public:
 
 private:
   int m_opno;
+  bool has_dest;
+  machine_mode dest_mode;
   expand_operand m_ops[MAX_OPERANDS];
 };
 
@@ -195,37 +235,41 @@ emit_pred_op (unsigned icode, rtx mask, rtx dest, rtx src, rtx len,
 	      machine_mode mask_mode, bool vlmax_p)
 {
   insn_expander<8> e;
-  machine_mode mode = GET_MODE (dest);
+  e.set_dest_and_mask (mask, dest, mask_mode);
 
-  e.add_output_operand (dest, mode);
+  e.add_input_operand (src, GET_MODE (src));
 
-  if (mask)
-    e.add_input_operand (mask, GET_MODE (mask));
-  else
-    e.add_all_one_mask_operand (mask_mode);
+  e.set_len_and_policy (len, vlmax_p);
 
-  e.add_vundef_operand (mode);
+  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src));
+}
 
-  e.add_input_operand (src, GET_MODE (src));
+/* Emit an RVV binop.  If one of SRC1 and SRC2 is a scalar operand, its mode is
+   specified using SCALAR_MODE.  */
+static void
+emit_pred_binop (unsigned icode, rtx mask, rtx dest, rtx src1, rtx src2,
+		 rtx len, machine_mode mask_mode, machine_mode scalar_mode,
+		 bool vlmax_p)
+{
+  insn_expander<9> e;
+  e.set_dest_and_mask (mask, dest, mask_mode);
 
-  if (len)
-    e.add_input_operand (len, Pmode);
-  else
-    {
-      rtx vlmax = gen_reg_rtx (Pmode);
-      emit_vlmax_vsetvl (mode, vlmax);
-      e.add_input_operand (vlmax, Pmode);
-    }
+  gcc_assert (VECTOR_MODE_P (GET_MODE (src1))
+	      || VECTOR_MODE_P (GET_MODE (src2)));
 
-  if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
-    e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
+  if (VECTOR_MODE_P (GET_MODE (src1)))
+    e.add_input_operand (src1, GET_MODE (src1));
+  else
+    e.add_input_operand (src1, scalar_mode);
 
-  if (vlmax_p)
-    e.add_avl_type_operand (avl_type::VLMAX);
+  if (VECTOR_MODE_P (GET_MODE (src2)))
+    e.add_input_operand (src2, GET_MODE (src2));
   else
-    e.add_avl_type_operand (avl_type::NONVLMAX);
+    e.add_input_operand (src2, scalar_mode);
 
-  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src));
+  e.set_len_and_policy (len, vlmax_p);
+
+  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src1) || MEM_P (src2));
 }
 
 void
@@ -248,49 +292,25 @@ emit_nonvlmax_op (unsigned icode, rtx dest, rtx src, rtx len,
   emit_pred_op (icode, NULL_RTX, dest, src, len, mask_mode, false);
 }
 
-/* Emit binary operations.  */
-
-static void
-emit_binop (unsigned icode, rtx *ops, machine_mode mask_mode,
-	    machine_mode scalar_mode)
+void
+emit_nonvlmax_binop (unsigned icode, rtx dest, rtx src1, rtx src2, rtx len,
+		     machine_mode mask_mode, machine_mode scalar_mode)
 {
-  insn_expander<9> e;
-  machine_mode mode = GET_MODE (ops[0]);
-  e.add_output_operand (ops[0], mode);
-  e.add_all_one_mask_operand (mask_mode);
-  e.add_vundef_operand (mode);
-  if (VECTOR_MODE_P (GET_MODE (ops[1])))
-    e.add_input_operand (ops[1], GET_MODE (ops[1]));
-  else
-    e.add_input_operand (ops[1], scalar_mode);
-  if (VECTOR_MODE_P (GET_MODE (ops[2])))
-    e.add_input_operand (ops[2], GET_MODE (ops[2]));
-  else
-    e.add_input_operand (ops[2], scalar_mode);
-  rtx vlmax = gen_reg_rtx (Pmode);
-  emit_vlmax_vsetvl (mode, vlmax);
-  e.add_input_operand (vlmax, Pmode);
-  e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
-  e.add_avl_type_operand (avl_type::VLMAX);
-  e.expand ((enum insn_code) icode, false);
+  emit_pred_binop (icode, NULL_RTX, dest, src1, src2, len, mask_mode,
+		   scalar_mode, len ? false : true);
 }
 
 /* Emit vid.v instruction.  */
 
 static void
-emit_index_op (rtx target, machine_mode mask_mode)
+emit_index_op (rtx dest, machine_mode mask_mode)
 {
   insn_expander<7> e;
-  machine_mode mode = GET_MODE (target);
-  e.add_output_operand (target, mode);
-  e.add_all_one_mask_operand (mask_mode);
-  e.add_vundef_operand (mode);
-  rtx vlmax = gen_reg_rtx (Pmode);
-  emit_vlmax_vsetvl (mode, vlmax);
-  e.add_input_operand (vlmax, Pmode);
-  e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
-  e.add_avl_type_operand (avl_type::VLMAX);
-  e.expand (code_for_pred_series (mode), false);
+  e.set_dest_and_mask (NULL, dest, mask_mode);
+
+  e.set_len_and_policy (NULL, true);
+
+  e.expand (code_for_pred_series (GET_MODE (dest)), false);
 }
 
 /* Expand series const vector.  */
@@ -324,15 +344,15 @@ expand_vec_series (rtx dest, rtx base, rtx step)
 	  /* Emit logical left shift operation.  */
 	  int shift = exact_log2 (INTVAL (step));
 	  rtx shift_amount = gen_int_mode (shift, Pmode);
-	  rtx ops[3] = {step_adj, vid, shift_amount};
 	  insn_code icode = code_for_pred_scalar (ASHIFT, mode);
-	  emit_binop (icode, ops, mask_mode, Pmode);
+	  emit_nonvlmax_binop (icode, step_adj, vid, shift_amount,
+			       NULL, mask_mode, Pmode);
 	}
       else
 	{
-	  rtx ops[3] = {step_adj, vid, step};
 	  insn_code icode = code_for_pred_scalar (MULT, mode);
-	  emit_binop (icode, ops, mask_mode, inner_mode);
+	  emit_nonvlmax_binop (icode, step_adj, vid, step,
+			       NULL, mask_mode, inner_mode);
 	}
     }
 
@@ -346,9 +366,9 @@ expand_vec_series (rtx dest, rtx base, rtx step)
   else
     {
       rtx result = gen_reg_rtx (mode);
-      rtx ops[3] = {result, step_adj, base};
       insn_code icode = code_for_pred_scalar (PLUS, mode);
-      emit_binop (icode, ops, mask_mode, inner_mode);
+      emit_nonvlmax_binop (icode, result, step_adj, base,
+			   NULL, mask_mode, inner_mode);
       emit_move_insn (dest, result);
     }
 }
-- 
2.40.0

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

* Re: [PATCH v2] RISC-V: Add vectorized binops and insn_expander helpers.
  2023-05-11 10:26       ` [PATCH v2] RISC-V: " Robin Dapp
@ 2023-05-11 10:34         ` juzhe.zhong
  2023-05-11 10:36           ` Robin Dapp
  0 siblings, 1 reply; 9+ messages in thread
From: juzhe.zhong @ 2023-05-11 10:34 UTC (permalink / raw)
  To: Robin Dapp, gcc-patches, kito.cheng, collison, palmer, jeffreyalaw
  Cc: Robin Dapp

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

LGTM. You should commit it now. Then I can rebase vec_init patch.



juzhe.zhong@rivai.ai
 
From: Robin Dapp
Date: 2023-05-11 18:26
To: 钟居哲; gcc-patches; kito.cheng; Michael Collison; palmer; Jeff Law
CC: rdapp.gcc
Subject: [PATCH v2] RISC-V: Add vectorized binops and insn_expander helpers.
Changes from v1:
 
- Rebase against Juzhe's vec_series patch.
- Get rid of redundant scalar mode setting.
 
 
This patch adds basic binary integer operations support.  It is based
on Michael Collison's work and makes use of the existing helpers in
riscv-c.cc.  It introduces emit_nonvlmax_binop which, in turn, uses
emit_pred_binop.  Setting the destination as well as the mask and the
length are factored out into separate functions.
 
gcc/ChangeLog:
 
* config/riscv/autovec.md (<optab><mode>3): Add integer binops.
* config/riscv/riscv-protos.h (emit_nonvlmax_binop): Declare.
* config/riscv/riscv-v.cc (emit_pred_op): New function.
(set_expander_dest_and_mask): New function.
(emit_pred_binop): New function.
(emit_nonvlmax_binop): New function.
 
Co-authored-by: Michael Collison <collison@rivosinc.com>
---
gcc/config/riscv/autovec.md     |  37 ++++++++
gcc/config/riscv/riscv-protos.h |   2 +
gcc/config/riscv/riscv-v.cc     | 148 ++++++++++++++++++--------------
3 files changed, 123 insertions(+), 64 deletions(-)
 
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 99dc4f046b0..e249f4be704 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -82,3 +82,40 @@ (define_expand "@vec_series<mode>"
     DONE;
   }
)
+
+;; ========================================================================
+;; == Vector operations
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] Binary operations
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vadd.vv/vsub.vv/...
+;; - vadd.vi/vsub.vi/...
+;; -------------------------------------------------------------------------
+
+(define_expand "<optab><mode>3"
+  [(set (match_operand:VI 0 "register_operand")
+    (any_int_binop:VI
+     (match_operand:VI 1 "<binop_rhs1_predicate>")
+     (match_operand:VI 2 "<binop_rhs2_predicate>")))]
+  "TARGET_VECTOR"
+{
+  if (!register_operand (operands[2], <MODE>mode))
+    {
+      rtx cst;
+      gcc_assert (const_vec_duplicate_p(operands[2], &cst));
+      riscv_vector::emit_nonvlmax_binop (code_for_pred_scalar
+ (<CODE>, <MODE>mode),
+ operands[0], operands[1], cst,
+ NULL, <VM>mode,
+ <VEL>mode);
+    }
+  else
+    riscv_vector::emit_nonvlmax_binop (code_for_pred
+        (<CODE>, <MODE>mode),
+        operands[0], operands[1], operands[2],
+        NULL, <VM>mode);
+  DONE;
+})
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index e8a728ae226..4d0589e502c 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -169,6 +169,8 @@ void emit_hard_vlmax_vsetvl (machine_mode, rtx);
void emit_vlmax_op (unsigned, rtx, rtx, machine_mode);
void emit_vlmax_op (unsigned, rtx, rtx, rtx, machine_mode);
void emit_nonvlmax_op (unsigned, rtx, rtx, rtx, machine_mode);
+void emit_nonvlmax_binop (unsigned, rtx, rtx, rtx, rtx, machine_mode,
+   machine_mode = VOIDmode);
enum vlmul_type get_vlmul (machine_mode);
unsigned int get_ratio (machine_mode);
unsigned int get_nf (machine_mode);
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 381e6601a17..8f46226d571 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -53,7 +53,7 @@ namespace riscv_vector {
template <int MAX_OPERANDS> class insn_expander
{
public:
-  insn_expander () : m_opno (0) {}
+  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);
@@ -84,6 +84,44 @@ public:
     add_input_operand (gen_int_mode (type, Pmode), Pmode);
   }
+  void set_dest_and_mask (rtx mask, rtx dest, machine_mode mask_mode)
+  {
+    dest_mode = GET_MODE (dest);
+    has_dest = true;
+
+    add_output_operand (dest, dest_mode);
+
+    if (mask)
+      add_input_operand (mask, GET_MODE (mask));
+    else
+      add_all_one_mask_operand (mask_mode);
+
+    add_vundef_operand (dest_mode);
+  }
+
+  void set_len_and_policy (rtx len, bool vlmax_p)
+    {
+      gcc_assert (has_dest);
+      gcc_assert (len || vlmax_p);
+
+      if (len)
+ add_input_operand (len, Pmode);
+      else
+ {
+   rtx vlmax = gen_reg_rtx (Pmode);
+   emit_vlmax_vsetvl (dest_mode, vlmax);
+   add_input_operand (vlmax, Pmode);
+ }
+
+      if (GET_MODE_CLASS (dest_mode) != MODE_VECTOR_BOOL)
+ add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
+
+      if (vlmax_p)
+ add_avl_type_operand (avl_type::VLMAX);
+      else
+ add_avl_type_operand (avl_type::NONVLMAX);
+    }
+
   void expand (enum insn_code icode, bool temporary_volatile_p = false)
   {
     if (temporary_volatile_p)
@@ -97,6 +135,8 @@ public:
private:
   int m_opno;
+  bool has_dest;
+  machine_mode dest_mode;
   expand_operand m_ops[MAX_OPERANDS];
};
@@ -195,37 +235,41 @@ emit_pred_op (unsigned icode, rtx mask, rtx dest, rtx src, rtx len,
      machine_mode mask_mode, bool vlmax_p)
{
   insn_expander<8> e;
-  machine_mode mode = GET_MODE (dest);
+  e.set_dest_and_mask (mask, dest, mask_mode);
-  e.add_output_operand (dest, mode);
+  e.add_input_operand (src, GET_MODE (src));
-  if (mask)
-    e.add_input_operand (mask, GET_MODE (mask));
-  else
-    e.add_all_one_mask_operand (mask_mode);
+  e.set_len_and_policy (len, vlmax_p);
-  e.add_vundef_operand (mode);
+  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src));
+}
-  e.add_input_operand (src, GET_MODE (src));
+/* Emit an RVV binop.  If one of SRC1 and SRC2 is a scalar operand, its mode is
+   specified using SCALAR_MODE.  */
+static void
+emit_pred_binop (unsigned icode, rtx mask, rtx dest, rtx src1, rtx src2,
+ rtx len, machine_mode mask_mode, machine_mode scalar_mode,
+ bool vlmax_p)
+{
+  insn_expander<9> e;
+  e.set_dest_and_mask (mask, dest, mask_mode);
-  if (len)
-    e.add_input_operand (len, Pmode);
-  else
-    {
-      rtx vlmax = gen_reg_rtx (Pmode);
-      emit_vlmax_vsetvl (mode, vlmax);
-      e.add_input_operand (vlmax, Pmode);
-    }
+  gcc_assert (VECTOR_MODE_P (GET_MODE (src1))
+       || VECTOR_MODE_P (GET_MODE (src2)));
-  if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
-    e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
+  if (VECTOR_MODE_P (GET_MODE (src1)))
+    e.add_input_operand (src1, GET_MODE (src1));
+  else
+    e.add_input_operand (src1, scalar_mode);
-  if (vlmax_p)
-    e.add_avl_type_operand (avl_type::VLMAX);
+  if (VECTOR_MODE_P (GET_MODE (src2)))
+    e.add_input_operand (src2, GET_MODE (src2));
   else
-    e.add_avl_type_operand (avl_type::NONVLMAX);
+    e.add_input_operand (src2, scalar_mode);
-  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src));
+  e.set_len_and_policy (len, vlmax_p);
+
+  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src1) || MEM_P (src2));
}
void
@@ -248,49 +292,25 @@ emit_nonvlmax_op (unsigned icode, rtx dest, rtx src, rtx len,
   emit_pred_op (icode, NULL_RTX, dest, src, len, mask_mode, false);
}
-/* Emit binary operations.  */
-
-static void
-emit_binop (unsigned icode, rtx *ops, machine_mode mask_mode,
-     machine_mode scalar_mode)
+void
+emit_nonvlmax_binop (unsigned icode, rtx dest, rtx src1, rtx src2, rtx len,
+      machine_mode mask_mode, machine_mode scalar_mode)
{
-  insn_expander<9> e;
-  machine_mode mode = GET_MODE (ops[0]);
-  e.add_output_operand (ops[0], mode);
-  e.add_all_one_mask_operand (mask_mode);
-  e.add_vundef_operand (mode);
-  if (VECTOR_MODE_P (GET_MODE (ops[1])))
-    e.add_input_operand (ops[1], GET_MODE (ops[1]));
-  else
-    e.add_input_operand (ops[1], scalar_mode);
-  if (VECTOR_MODE_P (GET_MODE (ops[2])))
-    e.add_input_operand (ops[2], GET_MODE (ops[2]));
-  else
-    e.add_input_operand (ops[2], scalar_mode);
-  rtx vlmax = gen_reg_rtx (Pmode);
-  emit_vlmax_vsetvl (mode, vlmax);
-  e.add_input_operand (vlmax, Pmode);
-  e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
-  e.add_avl_type_operand (avl_type::VLMAX);
-  e.expand ((enum insn_code) icode, false);
+  emit_pred_binop (icode, NULL_RTX, dest, src1, src2, len, mask_mode,
+    scalar_mode, len ? false : true);
}
/* Emit vid.v instruction.  */
static void
-emit_index_op (rtx target, machine_mode mask_mode)
+emit_index_op (rtx dest, machine_mode mask_mode)
{
   insn_expander<7> e;
-  machine_mode mode = GET_MODE (target);
-  e.add_output_operand (target, mode);
-  e.add_all_one_mask_operand (mask_mode);
-  e.add_vundef_operand (mode);
-  rtx vlmax = gen_reg_rtx (Pmode);
-  emit_vlmax_vsetvl (mode, vlmax);
-  e.add_input_operand (vlmax, Pmode);
-  e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ());
-  e.add_avl_type_operand (avl_type::VLMAX);
-  e.expand (code_for_pred_series (mode), false);
+  e.set_dest_and_mask (NULL, dest, mask_mode);
+
+  e.set_len_and_policy (NULL, true);
+
+  e.expand (code_for_pred_series (GET_MODE (dest)), false);
}
/* Expand series const vector.  */
@@ -324,15 +344,15 @@ expand_vec_series (rtx dest, rtx base, rtx step)
  /* Emit logical left shift operation.  */
  int shift = exact_log2 (INTVAL (step));
  rtx shift_amount = gen_int_mode (shift, Pmode);
-   rtx ops[3] = {step_adj, vid, shift_amount};
  insn_code icode = code_for_pred_scalar (ASHIFT, mode);
-   emit_binop (icode, ops, mask_mode, Pmode);
+   emit_nonvlmax_binop (icode, step_adj, vid, shift_amount,
+        NULL, mask_mode, Pmode);
}
       else
{
-   rtx ops[3] = {step_adj, vid, step};
  insn_code icode = code_for_pred_scalar (MULT, mode);
-   emit_binop (icode, ops, mask_mode, inner_mode);
+   emit_nonvlmax_binop (icode, step_adj, vid, step,
+        NULL, mask_mode, inner_mode);
}
     }
@@ -346,9 +366,9 @@ expand_vec_series (rtx dest, rtx base, rtx step)
   else
     {
       rtx result = gen_reg_rtx (mode);
-      rtx ops[3] = {result, step_adj, base};
       insn_code icode = code_for_pred_scalar (PLUS, mode);
-      emit_binop (icode, ops, mask_mode, inner_mode);
+      emit_nonvlmax_binop (icode, result, step_adj, base,
+    NULL, mask_mode, inner_mode);
       emit_move_insn (dest, result);
     }
}
-- 
2.40.0
 

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

* Re: [PATCH v2] RISC-V: Add vectorized binops and insn_expander helpers.
  2023-05-11 10:34         ` juzhe.zhong
@ 2023-05-11 10:36           ` Robin Dapp
  2023-05-11 10:38             ` juzhe.zhong
  0 siblings, 1 reply; 9+ messages in thread
From: Robin Dapp @ 2023-05-11 10:36 UTC (permalink / raw)
  To: juzhe.zhong, gcc-patches, kito.cheng, collison, palmer, jeffreyalaw

> LGTM. You should commit it now. Then I can rebase vec_init patch.

Would need an ACK/OK from Kito at least :)

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

* Re: Re: [PATCH v2] RISC-V: Add vectorized binops and insn_expander helpers.
  2023-05-11 10:36           ` Robin Dapp
@ 2023-05-11 10:38             ` juzhe.zhong
  2023-05-11 11:09               ` Kito Cheng
  0 siblings, 1 reply; 9+ messages in thread
From: juzhe.zhong @ 2023-05-11 10:38 UTC (permalink / raw)
  To: Robin Dapp, gcc-patches, kito.cheng, collison, palmer, jeffreyalaw

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

I just saw Kito has LGTM in V1 patch. 
Let's wait for Kito LGTM for V2.



juzhe.zhong@rivai.ai
 
From: Robin Dapp
Date: 2023-05-11 18:36
To: juzhe.zhong@rivai.ai; gcc-patches; kito.cheng; collison; palmer; jeffreyalaw
Subject: Re: [PATCH v2] RISC-V: Add vectorized binops and insn_expander helpers.
> LGTM. You should commit it now. Then I can rebase vec_init patch.
 
Would need an ACK/OK from Kito at least :)
 

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

* Re: Re: [PATCH v2] RISC-V: Add vectorized binops and insn_expander helpers.
  2023-05-11 10:38             ` juzhe.zhong
@ 2023-05-11 11:09               ` Kito Cheng
  0 siblings, 0 replies; 9+ messages in thread
From: Kito Cheng @ 2023-05-11 11:09 UTC (permalink / raw)
  To: 钟居哲
  Cc: Robin Dapp, gcc-patches, collison, palmer, jeffreyalaw

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

LGTM for v2 as well :)

juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai> 於 2023年5月11日 週四 18:39 寫道:

> I just saw Kito has LGTM in V1 patch.
> Let's wait for Kito LGTM for V2.
>
>
>
> juzhe.zhong@rivai.ai
>
> From: Robin Dapp
> Date: 2023-05-11 18:36
> To: juzhe.zhong@rivai.ai; gcc-patches; kito.cheng; collison; palmer;
> jeffreyalaw
> Subject: Re: [PATCH v2] RISC-V: Add vectorized binops and insn_expander
> helpers.
> > LGTM. You should commit it now. Then I can rebase vec_init patch.
>
> Would need an ACK/OK from Kito at least :)
>
>

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

end of thread, other threads:[~2023-05-11 11:10 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-10 15:24 [PATCH] riscv: Add vectorized binops and insn_expander helpers Robin Dapp
2023-05-10 15:43 ` 钟居哲
2023-05-10 18:02   ` Robin Dapp
2023-05-10 22:55     ` 钟居哲
2023-05-11 10:26       ` [PATCH v2] RISC-V: " Robin Dapp
2023-05-11 10:34         ` juzhe.zhong
2023-05-11 10:36           ` Robin Dapp
2023-05-11 10:38             ` juzhe.zhong
2023-05-11 11:09               ` Kito Cheng

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