From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2093) id AEFB83857B93; Fri, 17 Feb 2023 02:47:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AEFB83857B93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1676602044; bh=F2X4ogLAuJLnknvAmG661Y309eeEHPvjEVg+1/g6EEk=; h=From:To:Subject:Date:From; b=ZHlVWOcZN2lsNAN49rcXHLaC+fq217AOQ9Tq/s7pdfgcqtwqbX3FBXasBfrpfyRsQ sUV0ZMtHSczG9AtgqlC9BHz8uy/AwWI92qqVfEBFEbD1A9DOQQBiiZl8X28/Iy4PKW 65henBvxAihfy5Oe7DYWiUbFcvz21RPwx2lgU3BQ= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Kito Cheng To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-6110] RISC-V: Add RVV all mask C/C++ intrinsics support X-Act-Checkin: gcc X-Git-Author: Ju-Zhe Zhong X-Git-Refname: refs/heads/master X-Git-Oldrev: c2031252868015f8a8ad1c67362a8b37ce6f8030 X-Git-Newrev: 1ed93bc7ed88d1164bcccbd38a840b8b0a67961c Message-Id: <20230217024724.AEFB83857B93@sourceware.org> Date: Fri, 17 Feb 2023 02:47:24 +0000 (GMT) List-Id: https://gcc.gnu.org/g:1ed93bc7ed88d1164bcccbd38a840b8b0a67961c commit r13-6110-g1ed93bc7ed88d1164bcccbd38a840b8b0a67961c Author: Ju-Zhe Zhong 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_n): New pattern. (@pred_not): New pattern. (@pred_popcount): New pattern. (@pred_ffs): New pattern. (@pred_): New pattern. (@pred_iota): New pattern. (@pred_series): 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 +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 +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 +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 +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 vsetvl_obj; static CONSTEXPR const vsetvl vsetvlmax_obj; static CONSTEXPR const loadstore vle_obj; @@ -763,6 +942,25 @@ static CONSTEXPR const sat_op vssrl_obj; static CONSTEXPR const sat_op vssra_obj; static CONSTEXPR const vnclip vnclip_obj; static CONSTEXPR const vnclip vnclipu_obj; +static CONSTEXPR const mask_logic vmand_obj; +static CONSTEXPR const mask_nlogic vmnand_obj; +static CONSTEXPR const mask_notlogic vmandn_obj; +static CONSTEXPR const mask_logic vmxor_obj; +static CONSTEXPR const mask_logic vmor_obj; +static CONSTEXPR const mask_nlogic vmnor_obj; +static CONSTEXPR const mask_notlogic vmorn_obj; +static CONSTEXPR const mask_nlogic 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 vmsbf_obj; +static CONSTEXPR const mask_misc vmsif_obj; +static CONSTEXPR const mask_misc 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 _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 --> vop_. 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_ --> vop__. */ + 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) - && register_operand (operands[3], mode)" + && register_operand (operands[3], 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" "")]) ;; Dedicated pattern for vsm.v instruction since we can't reuse pred_mov pattern to include @@ -3809,7 +3824,7 @@ reg, CONSTM1_RTX (mode), undef, operands[3], operands[4], operands[5], operands[6], operands[7], operands[8])); emit_insn ( - gen_pred_andn (operands[0], CONSTM1_RTX (mode), undef, + gen_pred_andnot (operands[0], CONSTM1_RTX (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_n" +(define_insn "@pred_not" [(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" "") (set_attr "vl_op_idx" "4") (set (attr "avl_type") (symbol_ref "INTVAL (operands[5])"))]) + +(define_insn "@pred_popcount" + [(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" "")]) + +(define_insn "@pred_ffs" + [(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" "")]) + +(define_insn "@pred_" + [(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.m\t%0,%3%p1" + [(set_attr "type" "vmsfs") + (set_attr "mode" "")]) + +(define_insn "@pred_iota" + [(set (match_operand:VI 0 "register_operand" "=&vr") + (if_then_else:VI + (unspec: + [(match_operand: 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: 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" "")]) + +(define_insn "@pred_series" + [(set (match_operand:VI 0 "register_operand" "=vd, vr") + (if_then_else:VI + (unspec: + [(match_operand: 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" "")])