public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-6110] RISC-V: Add RVV all mask C/C++ intrinsics support
@ 2023-02-17  2:47 Kito Cheng
  0 siblings, 0 replies; only message in thread
From: Kito Cheng @ 2023-02-17  2:47 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:1ed93bc7ed88d1164bcccbd38a840b8b0a67961c

commit r13-6110-g1ed93bc7ed88d1164bcccbd38a840b8b0a67961c
Author: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
Date:   Thu Feb 16 11:30:01 2023 +0800

    RISC-V: Add RVV all mask C/C++ intrinsics support
    
    gcc/ChangeLog:
    
            * config/riscv/riscv-vector-builtins-bases.cc (class mask_logic): New
            class.
            (class mask_nlogic): Ditto.
            (class mask_notlogic): Ditto.
            (class vmmv): Ditto.
            (class vmclr): Ditto.
            (class vmset): Ditto.
            (class vmnot): Ditto.
            (class vcpop): Ditto.
            (class vfirst): Ditto.
            (class mask_misc): Ditto.
            (class viota): Ditto.
            (class vid): Ditto.
            (BASE): Ditto.
            * config/riscv/riscv-vector-builtins-bases.h: Ditto.
            * config/riscv/riscv-vector-builtins-functions.def (vmand): Ditto.
            (vmnand): Ditto.
            (vmandn): Ditto.
            (vmxor): Ditto.
            (vmor): Ditto.
            (vmnor): Ditto.
            (vmorn): Ditto.
            (vmxnor): Ditto.
            (vmmv): Ditto.
            (vmclr): Ditto.
            (vmset): Ditto.
            (vmnot): Ditto.
            (vcpop): Ditto.
            (vfirst): Ditto.
            (vmsbf): Ditto.
            (vmsif): Ditto.
            (vmsof): Ditto.
            (viota): Ditto.
            (vid): Ditto.
            * config/riscv/riscv-vector-builtins-shapes.cc (struct alu_def): Ditto.
            (struct mask_alu_def): Ditto.
            (SHAPE): Ditto.
            * config/riscv/riscv-vector-builtins-shapes.h: Ditto.
            * config/riscv/riscv-vector-builtins.cc: Ditto.
            * config/riscv/riscv-vsetvl.cc (pass_vsetvl::cleanup_insns): Fix bug
            for dest it scalar RVV intrinsics.
            * config/riscv/vector-iterators.md (sof): New iterator.
            * config/riscv/vector.md (@pred_<optab>n<mode>): New pattern.
            (@pred_<optab>not<mode>): New pattern.
            (@pred_popcount<VB:mode><P:mode>): New pattern.
            (@pred_ffs<VB:mode><P:mode>): New pattern.
            (@pred_<misc_op><mode>): New pattern.
            (@pred_iota<mode>): New pattern.
            (@pred_series<mode>): New pattern.

Diff:
---
 gcc/config/riscv/riscv-vector-builtins-bases.cc    | 217 +++++++++++++++++++++
 gcc/config/riscv/riscv-vector-builtins-bases.h     |  19 ++
 .../riscv/riscv-vector-builtins-functions.def      |  32 ++-
 gcc/config/riscv/riscv-vector-builtins-shapes.cc   |  38 ++++
 gcc/config/riscv/riscv-vector-builtins-shapes.h    |   1 +
 gcc/config/riscv/riscv-vector-builtins.cc          |  64 ++++++
 gcc/config/riscv/riscv-vsetvl.cc                   |   6 +-
 gcc/config/riscv/vector-iterators.md               |   9 +
 gcc/config/riscv/vector.md                         | 145 ++++++++++++--
 9 files changed, 511 insertions(+), 20 deletions(-)

diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index ba701482728..88142217e45 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -665,6 +665,185 @@ public:
   }
 };
 
+/* Implements vmand/vmnand/vmandn/vmxor/vmor/vmnor/vmorn/vmxnor  */
+template<rtx_code CODE>
+class mask_logic : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ()));
+  }
+};
+template<rtx_code CODE>
+class mask_nlogic : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_n (CODE, e.vector_mode ()));
+  }
+};
+template<rtx_code CODE>
+class mask_notlogic : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_not (CODE, e.vector_mode ()));
+  }
+};
+
+/* Implements vmmv.  */
+class vmmv : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_mov (e.vector_mode ()));
+  }
+};
+
+/* Implements vmclr.  */
+class vmclr : public function_base
+{
+public:
+  bool can_be_overloaded_p (enum predication_type_index) const override
+  {
+    return false;
+  }
+
+  rtx expand (function_expander &e) const override
+  {
+    machine_mode mode = TYPE_MODE (TREE_TYPE (e.exp));
+    e.add_all_one_mask_operand (mode);
+    e.add_vundef_operand (mode);
+    e.add_input_operand (mode, CONST0_RTX (mode));
+    e.add_input_operand (call_expr_nargs (e.exp) - 1);
+    e.add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
+    return e.generate_insn (code_for_pred_mov (e.vector_mode ()));
+  }
+};
+
+/* Implements vmset.  */
+class vmset : public function_base
+{
+public:
+  bool can_be_overloaded_p (enum predication_type_index) const override
+  {
+    return false;
+  }
+
+  rtx expand (function_expander &e) const override
+  {
+    machine_mode mode = TYPE_MODE (TREE_TYPE (e.exp));
+    e.add_all_one_mask_operand (mode);
+    e.add_vundef_operand (mode);
+    e.add_input_operand (mode, CONSTM1_RTX (mode));
+    e.add_input_operand (call_expr_nargs (e.exp) - 1);
+    e.add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
+    return e.generate_insn (code_for_pred_mov (e.vector_mode ()));
+  }
+};
+
+/* Implements vmnot.  */
+class vmnot : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_not (e.vector_mode ()));
+  }
+};
+
+/* Implements vcpop.  */
+class vcpop : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+  bool has_merge_operand_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_popcount (e.vector_mode (), Pmode));
+  }
+};
+
+/* Implements vfirst.  */
+class vfirst : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+  bool apply_mask_policy_p () const override { return false; }
+  bool has_merge_operand_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_ffs (e.vector_mode (), Pmode));
+  }
+};
+
+/* Implements vmsbf/vmsif/vmsof.  */
+template<int UNSPEC>
+class mask_misc : public function_base
+{
+public:
+  bool apply_tail_policy_p () const override { return false; }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred (UNSPEC, e.vector_mode ()));
+  }
+};
+
+/* Implements viota.  */
+class viota : public function_base
+{
+public:
+  bool can_be_overloaded_p (enum predication_type_index pred) const override
+  {
+    return pred == PRED_TYPE_tu || pred == PRED_TYPE_tum
+	   || pred == PRED_TYPE_tumu;
+  }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_iota (e.vector_mode ()));
+  }
+};
+
+/* Implements vid.  */
+class vid : public function_base
+{
+public:
+  bool can_be_overloaded_p (enum predication_type_index pred) const override
+  {
+    return pred == PRED_TYPE_tu || pred == PRED_TYPE_tum
+	   || pred == PRED_TYPE_tumu;
+  }
+
+  rtx expand (function_expander &e) const override
+  {
+    return e.use_exact_insn (code_for_pred_series (e.vector_mode ()));
+  }
+};
+
 static CONSTEXPR const vsetvl<false> vsetvl_obj;
 static CONSTEXPR const vsetvl<true> vsetvlmax_obj;
 static CONSTEXPR const loadstore<false, LST_UNIT_STRIDE, false> vle_obj;
@@ -763,6 +942,25 @@ static CONSTEXPR const sat_op<UNSPEC_VSSRL> vssrl_obj;
 static CONSTEXPR const sat_op<UNSPEC_VSSRA> vssra_obj;
 static CONSTEXPR const vnclip<UNSPEC_VNCLIP> vnclip_obj;
 static CONSTEXPR const vnclip<UNSPEC_VNCLIPU> vnclipu_obj;
+static CONSTEXPR const mask_logic<AND> vmand_obj;
+static CONSTEXPR const mask_nlogic<AND> vmnand_obj;
+static CONSTEXPR const mask_notlogic<AND> vmandn_obj;
+static CONSTEXPR const mask_logic<XOR> vmxor_obj;
+static CONSTEXPR const mask_logic<IOR> vmor_obj;
+static CONSTEXPR const mask_nlogic<IOR> vmnor_obj;
+static CONSTEXPR const mask_notlogic<IOR> vmorn_obj;
+static CONSTEXPR const mask_nlogic<XOR> vmxnor_obj;
+static CONSTEXPR const vmmv vmmv_obj;
+static CONSTEXPR const vmclr vmclr_obj;
+static CONSTEXPR const vmset vmset_obj;
+static CONSTEXPR const vmnot vmnot_obj;
+static CONSTEXPR const vcpop vcpop_obj;
+static CONSTEXPR const vfirst vfirst_obj;
+static CONSTEXPR const mask_misc<UNSPEC_VMSBF> vmsbf_obj;
+static CONSTEXPR const mask_misc<UNSPEC_VMSIF> vmsif_obj;
+static CONSTEXPR const mask_misc<UNSPEC_VMSOF> vmsof_obj;
+static CONSTEXPR const viota viota_obj;
+static CONSTEXPR const vid vid_obj;
 
 /* Declare the function base NAME, pointing it to an instance
    of class <NAME>_obj.  */
@@ -867,5 +1065,24 @@ BASE (vssra)
 BASE (vssrl)
 BASE (vnclip)
 BASE (vnclipu)
+BASE (vmand)
+BASE (vmnand)
+BASE (vmandn)
+BASE (vmxor)
+BASE (vmor)
+BASE (vmnor)
+BASE (vmorn)
+BASE (vmxnor)
+BASE (vmmv)
+BASE (vmclr)
+BASE (vmset)
+BASE (vmnot)
+BASE (vcpop)
+BASE (vfirst)
+BASE (vmsbf)
+BASE (vmsif)
+BASE (vmsof)
+BASE (viota)
+BASE (vid)
 
 } // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h b/gcc/config/riscv/riscv-vector-builtins-bases.h
index cb36f1f2699..e136cd91147 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.h
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.h
@@ -124,6 +124,25 @@ extern const function_base *const vnclip;
 extern const function_base *const vnclip;
 extern const function_base *const vnclipu;
 extern const function_base *const vnclipu;
+extern const function_base *const vmand;
+extern const function_base *const vmnand;
+extern const function_base *const vmandn;
+extern const function_base *const vmxor;
+extern const function_base *const vmor;
+extern const function_base *const vmnor;
+extern const function_base *const vmorn;
+extern const function_base *const vmxnor;
+extern const function_base *const vmmv;
+extern const function_base *const vmclr;
+extern const function_base *const vmset;
+extern const function_base *const vmnot;
+extern const function_base *const vcpop;
+extern const function_base *const vfirst;
+extern const function_base *const vmsbf;
+extern const function_base *const vmsif;
+extern const function_base *const vmsof;
+extern const function_base *const viota;
+extern const function_base *const vid;
 }
 
 } // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def b/gcc/config/riscv/riscv-vector-builtins-functions.def
index e6c19691d17..38bf1b694bb 100644
--- a/gcc/config/riscv/riscv-vector-builtins-functions.def
+++ b/gcc/config/riscv/riscv-vector-builtins-functions.def
@@ -277,7 +277,37 @@ DEF_RVV_FUNCTION (vnclip, narrow_alu, full_preds, i_narrow_shift_vwx_ops)
 
 /* TODO: 13. Vector Floating-Point Instructions.  */
 /* TODO: 14. Vector Reduction Operations.  */
-/* TODO: 15. Vector Mask Instructions.  */
+
+/* 15. Vector Mask Instructions.  */
+
+// 15.1. Vector Mask-Register Logical Instructions
+DEF_RVV_FUNCTION (vmand, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmnand, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmandn, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmxor, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmor, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmnor, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmorn, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmxnor, mask_alu, none_preds, b_mmm_ops)
+DEF_RVV_FUNCTION (vmmv, mask_alu, none_preds, b_mm_ops)
+DEF_RVV_FUNCTION (vmclr, mask_alu, none_preds, b_m_ops)
+DEF_RVV_FUNCTION (vmset, mask_alu, none_preds, b_m_ops)
+DEF_RVV_FUNCTION (vmnot, mask_alu, none_preds, b_mm_ops)
+// 15.2. Vector count population in mask vcpop.m
+DEF_RVV_FUNCTION (vcpop, mask_alu, none_m_preds, b_ulong_m_ops)
+// 15.3. vfirst find-first-set mask bit
+DEF_RVV_FUNCTION (vfirst, mask_alu, none_m_preds, b_long_m_ops)
+// 15.4. vmsbf.m set-before-first mask bit
+DEF_RVV_FUNCTION (vmsbf, mask_alu, none_m_mu_preds, b_mm_ops)
+// 15.5. vmsif.m set-including-first mask bit
+DEF_RVV_FUNCTION (vmsif, mask_alu, none_m_mu_preds, b_mm_ops)
+// 15.6. vmsof.m set-only-first mask bit
+DEF_RVV_FUNCTION (vmsof, mask_alu, none_m_mu_preds, b_mm_ops)
+// 15.8. Vector Iota Instruction
+DEF_RVV_FUNCTION (viota, mask_alu, full_preds, u_vm_ops)
+// 15.9. Vector Element Index Instruction
+DEF_RVV_FUNCTION (vid, alu, full_preds, u_v_ops)
+
 /* TODO: 16. Vector Permutation Instructions.  */
 
 #undef DEF_RVV_FUNCTION
diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
index 2836170323a..abf169dea4c 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
@@ -191,6 +191,10 @@ struct alu_def : public build_base
   char *get_name (function_builder &b, const function_instance &instance,
 		  bool overloaded_p) const override
   {
+    /* Return nullptr if it can not be overloaded.  */
+    if (overloaded_p && !instance.base->can_be_overloaded_p (instance.pred))
+      return nullptr;
+
     b.append_base_name (instance.base_name);
 
     /* vop<sew> --> vop<sew>_<op>. According to rvv-intrinsic-doc, _vv/_vx/_v
@@ -342,6 +346,39 @@ struct move_def : public build_base
 	b.append_name (type_suffixes[instance.type.index].vector);
       }
 
+    /* According to rvv-intrinsic-doc, it does not add "_m" suffix
+       for vop_m C++ overloaded API.  */
+    if (overloaded_p && instance.pred == PRED_TYPE_m)
+      return b.finish_name ();
+    b.append_name (predication_suffixes[instance.pred]);
+    return b.finish_name ();
+  }
+};
+
+/* mask_alu_def class.  */
+struct mask_alu_def : public build_base
+{
+  char *get_name (function_builder &b, const function_instance &instance,
+		  bool overloaded_p) const override
+  {
+    /* Return nullptr if it can not be overloaded.  */
+    if (overloaded_p && !instance.base->can_be_overloaded_p (instance.pred))
+      return nullptr;
+
+    b.append_base_name (instance.base_name);
+
+    if (instance.op_info->op == OP_TYPE_mm || instance.op_info->op == OP_TYPE_m)
+      if (!overloaded_p)
+	b.append_name (operand_suffixes[instance.op_info->op]);
+
+    /* vop<sew>_<op> --> vop<sew>_<op>_<type>.  */
+    if (!overloaded_p)
+      b.append_name (type_suffixes[instance.type.index].vector);
+
+    /* According to rvv-intrinsic-doc, it does not add "_m" suffix
+       for vop_m C++ overloaded API.  */
+    if (overloaded_p && instance.pred == PRED_TYPE_m)
+      return b.finish_name ();
     b.append_name (predication_suffixes[instance.pred]);
     return b.finish_name ();
   }
@@ -357,5 +394,6 @@ SHAPE(no_mask_policy, no_mask_policy)
 SHAPE(return_mask, return_mask)
 SHAPE(narrow_alu, narrow_alu)
 SHAPE(move, move)
+SHAPE(mask_alu, mask_alu)
 
 } // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.h b/gcc/config/riscv/riscv-vector-builtins-shapes.h
index 91c174f56cd..406abefdb10 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.h
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h
@@ -34,6 +34,7 @@ extern const function_shape *const no_mask_policy;
 extern const function_shape *const return_mask;
 extern const function_shape *const narrow_alu;
 extern const function_shape *const move;
+extern const function_shape *const mask_alu;
 }
 
 } // end namespace riscv_vector
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 4ca5a88cbea..3747cad672f 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -231,6 +231,10 @@ static CONSTEXPR const rvv_arg_type_info rvv_arg_type_info_end
 static CONSTEXPR const rvv_arg_type_info void_args[]
   = {rvv_arg_type_info (RVV_BASE_void), rvv_arg_type_info_end};
 
+/* A list of args for size_t func () function.  */
+static CONSTEXPR const rvv_arg_type_info end_args[]
+  = {rvv_arg_type_info_end};
+
 /* A list of args for size_t func (size_t) function.  */
 static CONSTEXPR const rvv_arg_type_info size_args[]
   = {rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end};
@@ -371,6 +375,10 @@ static CONSTEXPR const rvv_arg_type_info shift_wv_args[]
 static CONSTEXPR const rvv_arg_type_info v_args[]
   = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info_end};
 
+/* A list of args for vector_type func (vector_type) function.  */
+static CONSTEXPR const rvv_arg_type_info m_args[]
+  = {rvv_arg_type_info (RVV_BASE_mask), rvv_arg_type_info_end};
+
 /* A list of args for vector_type func (scalar_type) function.  */
 static CONSTEXPR const rvv_arg_type_info x_args[]
   = {rvv_arg_type_info (RVV_BASE_scalar), rvv_arg_type_info_end};
@@ -539,6 +547,62 @@ static CONSTEXPR const rvv_op_info b_v_scalar_ptr_ops
      rvv_arg_type_info (RVV_BASE_void), /* Return type */
      scalar_ptr_args /* Args */};
 
+/* A static operand information for vector_type func (vector_type, vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_mmm_ops
+  = {b_ops,				  /* Types */
+     OP_TYPE_mm,			  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vv_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_mm_ops
+  = {b_ops,				  /* Types */
+     OP_TYPE_m,				  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     v_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_vm_ops
+  = {u_ops,				  /* Types */
+     OP_TYPE_m,				  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     m_args /* Args */};
+
+/* A static operand information for vector_type func ()
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_m_ops
+  = {b_ops,				  /* Types */
+     OP_TYPE_m,				  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     end_args /* Args */};
+
+/* A static operand information for vector_type func ()
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_v_ops
+  = {u_ops,				  /* Types */
+     OP_TYPE_v,				  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     end_args /* Args */};
+
+/* A static operand information for unsigned long func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_ulong_m_ops
+  = {b_ops,					 /* Types */
+     OP_TYPE_m,					 /* Suffix */
+     rvv_arg_type_info (RVV_BASE_unsigned_long), /* Return type */
+     v_args /* Args */};
+
+/* A static operand information for long func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_long_m_ops
+  = {b_ops,				/* Types */
+     OP_TYPE_m,				/* Suffix */
+     rvv_arg_type_info (RVV_BASE_long), /* Return type */
+     v_args /* Args */};
+
 /* A static operand information for vector_type func (const scalar_type *,
  * ptrdiff_t) function registration. */
 static CONSTEXPR const rvv_op_info all_v_scalar_const_ptr_ptrdiff_ops
diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index 77c62e2d8f3..3fbdd862242 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -3349,7 +3349,7 @@ pass_vsetvl::cleanup_insns (void) const
 	  if (!has_vl_op (rinsn) || !REG_P (get_vl (rinsn)))
 	    continue;
 	  rtx avl = get_vl (rinsn);
-	  if (count_occurrences (PATTERN (rinsn), avl, true) == 1)
+	  if (count_occurrences (PATTERN (rinsn), avl, 0) == 1)
 	    {
 	      /* Get the list of uses for the new instruction.  */
 	      auto attempt = crtl->ssa->new_change_attempt ();
@@ -3363,7 +3363,9 @@ pass_vsetvl::cleanup_insns (void) const
 	      use_array new_uses = use_array (uses_builder.finish ());
 	      change.new_uses = new_uses;
 	      change.move_range = insn->ebb ()->insn_range ();
-	      rtx pat = simplify_replace_rtx (PATTERN (rinsn), avl, const0_rtx);
+	      rtx set = single_set (rinsn);
+	      rtx src = simplify_replace_rtx (SET_SRC (set), avl, const0_rtx);
+	      rtx pat = gen_rtx_SET (SET_DEST (set), src);
 	      gcc_assert (change_insn (crtl->ssa, change, insn, pat));
 	    }
 	}
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index c8b24150f4e..023b0b329c4 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -49,6 +49,11 @@
   UNSPEC_VASUBU
   UNSPEC_VASUB
   UNSPEC_VSMUL
+
+  UNSPEC_VMSBF
+  UNSPEC_VMSIF
+  UNSPEC_VMSOF
+  UNSPEC_VIOTA
 ])
 
 (define_mode_iterator V [
@@ -293,6 +298,8 @@
 			      	    UNSPEC_VASUBU UNSPEC_VASUB UNSPEC_VSMUL])
 (define_int_iterator VSAT_SHIFT_OP [UNSPEC_VSSRL UNSPEC_VSSRA])
 
+(define_int_iterator VMISC [UNSPEC_VMSBF UNSPEC_VMSIF UNSPEC_VMSOF])
+
 (define_int_attr order [
   (UNSPEC_ORDERED "o") (UNSPEC_UNORDERED "u")
 ])
@@ -309,6 +316,8 @@
 			 	(UNSPEC_VSSRA "vsshift") (UNSPEC_VNCLIP "vnclip")
 				(UNSPEC_VNCLIPU "vnclip")])
 
+(define_int_attr misc_op [(UNSPEC_VMSBF "sbf") (UNSPEC_VMSIF "sif") (UNSPEC_VMSOF "sof")])
+
 (define_code_iterator any_int_binop [plus minus and ior xor ashift ashiftrt lshiftrt
   smax umax smin umin mult div udiv mod umod
 ])
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index c897a365819..c131738c75f 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -146,7 +146,8 @@
 			  vialu,vshift,vicmp,vimul,vidiv,vsalu,\
 			  vext,viwalu,viwmul,vicalu,vnshift,\
 			  vimuladd,vimerge,vaalu,vsmul,vsshift,\
-			  vnclip,viminmax,viwmuladd")
+			  vnclip,viminmax,viwmuladd,vmpop,vmffs,vmsfs,\
+			  vmiota,vmidx")
 	   (const_int INVALID_ATTRIBUTE)
 	 (eq_attr "mode" "VNx1QI,VNx1BI")
 	   (symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)")
@@ -198,7 +199,8 @@
 (define_attr "merge_op_idx" ""
 	(cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu,vldux,vldox,vicmp,\
 				vialu,vshift,viminmax,vimul,vidiv,vsalu,vext,viwalu,\
-				viwmul,vnshift,vaalu,vsmul,vsshift,vnclip")
+				viwmul,vnshift,vaalu,vsmul,vsshift,vnclip,vmsfs,\
+				vmiota,vmidx")
 	       (const_int 2)
 
 	       (eq_attr "type" "vimerge")
@@ -211,7 +213,7 @@
 ;; The index of operand[] to get the avl op.
 (define_attr "vl_op_idx" ""
   (cond [(eq_attr "type" "vlde,vste,vimov,vfmov,vldm,vstm,vmalu,vsts,vstux,\
-			  vstox,vext")
+			  vstox,vext,vmsfs,vmiota")
 	   (const_int 4)
 
 	 ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
@@ -226,16 +228,16 @@
 			  vsshift,vnclip")
 	   (const_int 5)
 
-	 (eq_attr "type" "vicmp")
+	 (eq_attr "type" "vicmp,vimuladd,viwmuladd")
 	   (const_int 6)
 
-	 (eq_attr "type" "vimuladd,viwmuladd")
-	   (const_int 6)]
+	 (eq_attr "type" "vmpop,vmffs,vmidx")
+	   (const_int 3)]
   (const_int INVALID_ATTRIBUTE)))
 
 ;; The tail policy op value.
 (define_attr "ta" ""
-  (cond [(eq_attr "type" "vlde,vimov,vfmov,vext")
+  (cond [(eq_attr "type" "vlde,vimov,vfmov,vext,vmiota")
 	   (symbol_ref "riscv_vector::get_ta(operands[5])")
 
 	 ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
@@ -251,12 +253,15 @@
 	   (symbol_ref "riscv_vector::get_ta(operands[6])")
 
 	 (eq_attr "type" "vimuladd,viwmuladd")
-	   (symbol_ref "riscv_vector::get_ta(operands[7])")]
+	   (symbol_ref "riscv_vector::get_ta(operands[7])")
+
+	 (eq_attr "type" "vmidx")
+	   (symbol_ref "riscv_vector::get_ta(operands[4])")]
 	(const_int INVALID_ATTRIBUTE)))
 
 ;; The mask policy op value.
 (define_attr "ma" ""
-  (cond [(eq_attr "type" "vlde,vext")
+  (cond [(eq_attr "type" "vlde,vext,vmiota")
 	   (symbol_ref "riscv_vector::get_ma(operands[6])")
 
 	 ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
@@ -272,7 +277,10 @@
 	   (symbol_ref "riscv_vector::get_ma(operands[7])")
 
 	 (eq_attr "type" "vimuladd,viwmuladd")
-	   (symbol_ref "riscv_vector::get_ma(operands[8])")]
+	   (symbol_ref "riscv_vector::get_ma(operands[8])")
+
+	 (eq_attr "type" "vmsfs,vmidx")
+	   (symbol_ref "riscv_vector::get_ma(operands[5])")]
 	(const_int INVALID_ATTRIBUTE)))
 
 ;; The avl type value.
@@ -297,7 +305,13 @@
 	   (symbol_ref "INTVAL (operands[5])")
 
 	 (eq_attr "type" "vimuladd,viwmuladd")
-	   (symbol_ref "INTVAL (operands[9])")]
+	   (symbol_ref "INTVAL (operands[9])")
+
+	 (eq_attr "type" "vmsfs,vmidx")
+	   (symbol_ref "INTVAL (operands[6])")
+
+	 (eq_attr "type" "vmpop,vmffs")
+	   (symbol_ref "INTVAL (operands[4])")]
 	(const_int INVALID_ATTRIBUTE)))
 
 ;; -----------------------------------------------------------------
@@ -795,14 +809,15 @@
   "@
    vlm.v\t%0,%3
    vsm.v\t%3,%0
-   #
+   vmmv.m\t%0,%3
    vmclr.m\t%0
    vmset.m\t%0"
   "&& register_operand (operands[0], <MODE>mode)
-   && register_operand (operands[3], <MODE>mode)"
+   && register_operand (operands[3], <MODE>mode)
+   && INTVAL (operands[5]) == riscv_vector::VLMAX"
   [(set (match_dup 0) (match_dup 3))]
   ""
-  [(set_attr "type" "vldm,vstm,vimov,vmalu,vmalu")
+  [(set_attr "type" "vldm,vstm,vmalu,vmalu,vmalu")
    (set_attr "mode" "<MODE>")])
 
 ;; Dedicated pattern for vsm.v instruction since we can't reuse pred_mov pattern to include
@@ -3809,7 +3824,7 @@
 		reg, CONSTM1_RTX (<VM>mode), undef, operands[3], operands[4],
 		operands[5], operands[6], operands[7], operands[8]));
 	      emit_insn (
-		gen_pred_andn<vm> (operands[0], CONSTM1_RTX (<VM>mode), undef,
+		gen_pred_andnot<vm> (operands[0], CONSTM1_RTX (<VM>mode), undef,
 				   operands[1], reg, operands[6], operands[8]));
 	    }
 	  else
@@ -4471,6 +4486,13 @@
 ;; -------------------------------------------------------------------------------
 ;; Includes:
 ;; - 15.1 Vector Mask-Register Logical Instructions
+;; - 15.2 Vector count population in mask vcpop.m
+;; - 15.3 vfirst find-first-set mask bit
+;; - 15.4 vmsbf.m set-before-first mask bit
+;; - 15.5 vmsif.m set-including-first mask bit
+;; - 15.6 vmsof.m set-only-first mask bit
+;; - 15.8 Vector Iota Instruction
+;; - 15.9 Vector Element Index Instruction
 ;; -------------------------------------------------------------------------------
 
 ;; We keep this pattern same as pred_mov so that we can gain more optimizations.
@@ -4517,7 +4539,7 @@
    (set_attr "vl_op_idx" "5")
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[6])"))])
 
-(define_insn "@pred_<optab>n<mode>"
+(define_insn "@pred_<optab>not<mode>"
   [(set (match_operand:VB 0 "register_operand"                   "=vr")
 	(if_then_else:VB
 	  (unspec:VB
@@ -4551,8 +4573,97 @@
 	    (match_operand:VB 3 "register_operand"               " vr"))
 	  (match_operand:VB 2 "vector_undef_operand"             " vu")))]
   "TARGET_VECTOR"
-  "vmnot.mm\t%0,%3"
+  "vmnot.m\t%0,%3"
   [(set_attr "type" "vmalu")
    (set_attr "mode" "<MODE>")
    (set_attr "vl_op_idx" "4")
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))])
+
+(define_insn "@pred_popcount<VB:mode><P:mode>"
+  [(set (match_operand:P 0 "register_operand"               "=r")
+	(popcount:P
+	  (unspec:VB
+	    [(and:VB
+	       (match_operand:VB 1 "vector_mask_operand" "vmWc1")
+	       (match_operand:VB 2 "register_operand"    "   vr"))
+	     (match_operand 3 "vector_length_operand"    "   rK")
+	     (match_operand 4 "const_int_operand"        "    i")
+	     (reg:SI VL_REGNUM)
+	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)))]
+  "TARGET_VECTOR"
+  "vcpop.m\t%0,%2%p1"
+  [(set_attr "type" "vmpop")
+   (set_attr "mode" "<VB:MODE>")])
+
+(define_insn "@pred_ffs<VB:mode><P:mode>"
+  [(set (match_operand:P 0 "register_operand"                 "=r")
+	(plus:P
+	  (ffs:P
+	    (unspec:VB
+	      [(and:VB
+	         (match_operand:VB 1 "vector_mask_operand" "vmWc1")
+	         (match_operand:VB 2 "register_operand"    "   vr"))
+	       (match_operand 3 "vector_length_operand"    "   rK")
+	       (match_operand 4 "const_int_operand"        "    i")
+	       (reg:SI VL_REGNUM)
+	       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE))
+	  (const_int -1)))]
+  "TARGET_VECTOR"
+  "vfirst.m\t%0,%2%p1"
+  [(set_attr "type" "vmffs")
+   (set_attr "mode" "<VB:MODE>")])
+
+(define_insn "@pred_<misc_op><mode>"
+  [(set (match_operand:VB 0 "register_operand"          "=&vr")
+	(if_then_else:VB
+	  (unspec:VB
+	    [(match_operand:VB 1 "vector_mask_operand" "vmWc1")
+	     (match_operand 4 "vector_length_operand"  "   rK")
+	     (match_operand 5 "const_int_operand"      "    i")
+	     (match_operand 6 "const_int_operand"      "    i")
+	     (reg:SI VL_REGNUM)
+	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+	  (unspec:VB
+	    [(match_operand:VB 3 "register_operand"    "   vr")] VMISC)
+	  (match_operand:VB 2 "vector_merge_operand"   "  0vu")))]
+  "TARGET_VECTOR"
+  "vm<misc_op>.m\t%0,%3%p1"
+  [(set_attr "type" "vmsfs")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_iota<mode>"
+  [(set (match_operand:VI 0 "register_operand"            "=&vr")
+	(if_then_else:VI
+	  (unspec:<VM>
+	    [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+	     (match_operand 4 "vector_length_operand"    "   rK")
+	     (match_operand 5 "const_int_operand"        "    i")
+	     (match_operand 6 "const_int_operand"        "    i")
+	     (match_operand 7 "const_int_operand"        "    i")
+	     (reg:SI VL_REGNUM)
+	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+	  (unspec:VI
+	    [(match_operand:<VM> 3 "register_operand"    "   vr")] UNSPEC_VIOTA)
+	  (match_operand:VI 2 "vector_merge_operand"     "  0vu")))]
+  "TARGET_VECTOR"
+  "viota.m\t%0,%3%p1"
+  [(set_attr "type" "vmiota")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_series<mode>"
+  [(set (match_operand:VI 0 "register_operand"           "=vd, vr")
+	(if_then_else:VI
+	  (unspec:<VM>
+	    [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1")
+	     (match_operand 3 "vector_length_operand"    " rK, rK")
+	     (match_operand 4 "const_int_operand"        "  i,  i")
+	     (match_operand 5 "const_int_operand"        "  i,  i")
+	     (match_operand 6 "const_int_operand"        "  i,  i")
+	     (reg:SI VL_REGNUM)
+	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+	  (vec_series:VI (const_int 0) (const_int 1))
+	  (match_operand:VI 2 "vector_merge_operand"     "0vu,0vu")))]
+  "TARGET_VECTOR"
+  "vid.v\t%0%p1"
+  [(set_attr "type" "vmidx")
+   (set_attr "mode" "<MODE>")])

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-02-17  2:47 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-17  2:47 [gcc r13-6110] RISC-V: Add RVV all mask C/C++ intrinsics support 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).