Hi Robin and Juzhe,

Just took a look and I like the approach.

On 4/26/23 19:43, juzhe.zhong wrote:
Yeah,Robin stuff is what I want and is making perfect sense for me.
---- Replied Message ----
From    Robin Dapp<rdapp....@gmail.com> <mailto:rdapp....@gmail.com>
Date    04/27/2023 02:15
To juzhe.zh...@rivai.ai<juzhe.zh...@rivai.ai> <mailto:juzhe.zh...@rivai.ai>,
collison<colli...@rivosinc.com> <mailto:colli...@rivosinc.com>,
gcc-patches<gcc-patches@gcc.gnu.org> <mailto:gcc-patches@gcc.gnu.org>
Cc      jeffreyalaw<jeffreya...@gmail.com> <mailto:jeffreya...@gmail.com>,
Kito.cheng<kito.ch...@sifive.com> <mailto:kito.ch...@sifive.com>,
kito.cheng<kito.ch...@gmail.com> <mailto:kito.ch...@gmail.com>,
palmer<pal...@dabbelt.com> <mailto:pal...@dabbelt.com>,
palmer<pal...@rivosinc.com> <mailto:pal...@rivosinc.com>
Subject Re: [PATCH v4 05/10] RISC-V:autovec: Add autovectorization patterns for binary integer operations

Hi Michael,

I have the diff below for the binops in my tree locally.
Maybe something like this works for you? Untested but compiles and
the expander helpers would need to be fortified obviously.

Regards
Robin

--

gcc/ChangeLog:

       * config/riscv/autovec.md (<optab><mode>3): New binops expander.
       * config/riscv/riscv-protos.h (emit_nonvlmax_binop): Define.
       * config/riscv/riscv-v.cc (emit_pred_binop): New function.
       (emit_nonvlmax_binop): New function.
       * config/riscv/vector-iterators.md: New iterator.
---
gcc/config/riscv/autovec.md          | 12 ++++
gcc/config/riscv/riscv-protos.h      |  1 +
gcc/config/riscv/riscv-v.cc          | 89 ++++++++++++++++++++--------
gcc/config/riscv/vector-iterators.md | 20 +++++++
4 files changed, 97 insertions(+), 25 deletions(-)

diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index b5d46ff57ab..c21d241f426 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -47,3 +47,15 @@ (define_expand "len_store_<mode>"
                 operands[1], operands[2], <VM>mode);
  DONE;
})
+
+(define_expand "<optab><mode>3"
+  [(set (match_operand:VI 0 "register_operand")
+    (any_int_binop:VI (match_operand:VI 1 "register_operand")
+              (match_operand:VI 2 "register_operand")))]
+  "TARGET_VECTOR"
+{
+  riscv_vector::emit_nonvlmax_binop (code_for_pred (<ANY_INT_BINOP>, <MODE>mode),
+                     operands[0], operands[1], operands[2],
+                     gen_reg_rtx (Pmode), <VM>mode);
+  DONE;
+})
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index f6ea6846736..5cca543c773 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -163,6 +163,7 @@ 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);
enum vlmul_type get_vlmul (machine_mode);
unsigned int get_ratio (machine_mode);
int get_ta (rtx);
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 5e69427ac54..98ebc052340 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -52,7 +52,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);
@@ -83,6 +83,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)
@@ -96,6 +134,8 @@ public:

private:
  int m_opno;
+  bool has_dest;
+  machine_mode dest_mode;
  expand_operand m_ops[MAX_OPERANDS];
};

@@ -183,37 +223,29 @@ 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);
-
-  if (mask)
-    e.add_input_operand (mask, GET_MODE (mask));
-  else
-    e.add_all_one_mask_operand (mask_mode);
+  e.add_input_operand (src, GET_MODE (src));

-  e.add_vundef_operand (mode);
+  e.set_len_and_policy (len, vlmax_p);

-  e.add_input_operand (src, GET_MODE (src));
+  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (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_binop (unsigned icode, rtx mask, rtx dest, rtx src1, rtx src2,
+         rtx len, machine_mode mask_mode, bool vlmax_p)
+{
+  insn_expander<9> 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 (src1, GET_MODE (src1));
+  e.add_input_operand (src2, GET_MODE (src2));

-  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));
+  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src1) || MEM_P (src2));
}

void
@@ -236,6 +268,13 @@ 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)
+{
+  emit_pred_binop (icode, NULL_RTX, dest, src1, src2, len, mask_mode, 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 a8e856161d3..7cf21751d2f 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -934,6 +934,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 ANY_INT_BINOP [
+    (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
--
2.40.0


Reply via email to