From patchwork Tue Feb 7 06:14:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "juzhe.zhong@rivai.ai" X-Patchwork-Id: 64403 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4A8FE3858289 for ; Tue, 7 Feb 2023 06:15:00 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtpbg156.qq.com (smtpbg156.qq.com [15.184.82.18]) by sourceware.org (Postfix) with ESMTPS id 8023E3858D1E for ; Tue, 7 Feb 2023 06:14:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8023E3858D1E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=rivai.ai Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=rivai.ai X-QQ-mid: bizesmtp74t1675750467tee37shx Received: from server1.localdomain ( [58.60.1.22]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 07 Feb 2023 14:14:26 +0800 (CST) X-QQ-SSF: 01400000000000E0L000000A0000000 X-QQ-FEAT: QityeSR92A3RBFnPnpO5fl+2UtcLiJ9eg70+arXnP7BzFLdj6aosv8CSY2ZxV L+K0mJC8/R9hVIuw/6FG/0gmyRjfEJggqLYGMkGBlaWJKm8CPoE/oHY36QtpEAIIjJ+1A5a UdwBO+tLY6Su1XvSsoQ63nzcDn2W0pP66SIIiGAZjTwjfhTT1f8Td6SY7IYY0nRdUhjSc7w EkuyH2ngHA+QhG9s1y97Jc+JaUnjTfi3/ZGRuEz3gdw5v2XfZOtdRpUiL0lw3PQuUvaCW2G 0l+CH1bXW60uv2l+a+gA5RUx0yrpJNNU2mfCpF/A2kZWKpZKt4hloYAeHo52T9XHTEI8/Sn GApsxeXk2F2Dif6y+QhJyVN9dhpp4VQbBT1Vx8+DHS+f93hmCYuxMesMjWL3v4EDWxAb0Ae QOyzzUHz0Qs= X-QQ-GoodBg: 2 From: juzhe.zhong@rivai.ai To: gcc-patches@gcc.gnu.org Cc: kito.cheng@gmail.com, Ju-Zhe Zhong Subject: [PATCH] RISC-V: Add integer widening instructions Date: Tue, 7 Feb 2023 14:14:24 +0800 Message-Id: <20230207061424.32134-1-juzhe.zhong@rivai.ai> X-Mailer: git-send-email 2.36.1 MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:rivai.ai:qybglogicsvr:qybglogicsvr7 X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_ASCII_DIVIDERS, KAM_DMARC_STATUS, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Ju-Zhe Zhong gcc/ChangeLog: * config/riscv/riscv-vector-builtins-bases.cc (class widen_binop): New class. (class vwmulsu): Ditto. (class vwcvt): Ditto. (BASE): Add integer widening support. * config/riscv/riscv-vector-builtins-bases.h: Ditto * config/riscv/riscv-vector-builtins-functions.def (vwadd): New class. (vwsub): New class. (vwmul): New class. (vwmulu): New class. (vwmulsu): New class. (vwaddu): New class. (vwsubu): New class. (vwcvt_x): New class. (vwcvtu_x): New class. * config/riscv/riscv-vector-builtins-shapes.cc (struct alu_def): New class. (struct widen_alu_def): New class. (SHAPE): New class. * config/riscv/riscv-vector-builtins-shapes.h: New class. * config/riscv/riscv-vector-builtins.cc (rvv_arg_type_info::get_base_vector_type): Add integer widening support. (rvv_arg_type_info::get_tree_type): Ditto. * config/riscv/riscv-vector-builtins.def (x_x_v): Change into "x_v" (x_v): Ditto. * config/riscv/riscv-vector-builtins.h (enum rvv_base_type): Add integer widening support. * config/riscv/riscv-vsetvl.cc (change_insn): Fix reg_equal use bug. * config/riscv/riscv.h (X0_REGNUM): New constant. * config/riscv/vector-iterators.md: New iterators. * config/riscv/vector.md (@pred_dual_widen_): New pattern. (@pred_dual_widen__scalar): Ditto. (@pred_single_widen_): Ditto. (@pred_single_widen__scalar): Ditto. (@pred_widen_mulsu): Ditto. (@pred_widen_mulsu_scalar): Ditto. (@pred_): Ditto. --- .../riscv/riscv-vector-builtins-bases.cc | 75 +++++++ .../riscv/riscv-vector-builtins-bases.h | 10 + .../riscv/riscv-vector-builtins-functions.def | 24 ++ .../riscv/riscv-vector-builtins-shapes.cc | 30 ++- .../riscv/riscv-vector-builtins-shapes.h | 1 + gcc/config/riscv/riscv-vector-builtins.cc | 151 +++++++++++++ gcc/config/riscv/riscv-vector-builtins.def | 2 +- gcc/config/riscv/riscv-vector-builtins.h | 3 + gcc/config/riscv/riscv-vsetvl.cc | 40 ++++ gcc/config/riscv/riscv.h | 3 - gcc/config/riscv/vector-iterators.md | 8 + gcc/config/riscv/vector.md | 205 +++++++++++++++++- 12 files changed, 539 insertions(+), 13 deletions(-) diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index 43f815156d8..e14a1854eee 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -239,6 +239,63 @@ public: } }; +/* Implements vwadd/vwsub/vwmul. */ +template +class widen_binop : public function_base +{ +public: + rtx expand (function_expander &e) const override + { + switch (e.op_info->op) + { + case OP_TYPE_vv: + return e.use_exact_insn ( + code_for_pred_dual_widen (CODE1, CODE2, e.vector_mode ())); + case OP_TYPE_vx: + return e.use_exact_insn ( + code_for_pred_dual_widen_scalar (CODE1, CODE2, e.vector_mode ())); + case OP_TYPE_wv: + return e.use_exact_insn ( + code_for_pred_single_widen (CODE1, CODE2, e.vector_mode ())); + case OP_TYPE_wx: + return e.use_exact_insn ( + code_for_pred_single_widen_scalar (CODE1, CODE2, e.vector_mode ())); + default: + gcc_unreachable (); + } + } +}; + +/* Implements vwmulsu. */ +class vwmulsu : public function_base +{ +public: + rtx expand (function_expander &e) const override + { + switch (e.op_info->op) + { + case OP_TYPE_vv: + return e.use_exact_insn (code_for_pred_widen_mulsu (e.vector_mode ())); + case OP_TYPE_vx: + return e.use_exact_insn ( + code_for_pred_widen_mulsu_scalar (e.vector_mode ())); + default: + gcc_unreachable (); + } + } +}; + +/* Implements vwcvt. */ +template +class vwcvt : public function_base +{ +public: + rtx expand (function_expander &e) const override + { + return e.use_exact_insn (code_for_pred (CODE, e.vector_mode ())); + } +}; + static CONSTEXPR const vsetvl vsetvl_obj; static CONSTEXPR const vsetvl vsetvlmax_obj; static CONSTEXPR const loadstore vle_obj; @@ -288,6 +345,15 @@ static CONSTEXPR const unop vneg_obj; static CONSTEXPR const unop vnot_obj; static CONSTEXPR const ext vsext_obj; static CONSTEXPR const ext vzext_obj; +static CONSTEXPR const widen_binopvwadd_obj; +static CONSTEXPR const widen_binopvwsub_obj; +static CONSTEXPR const widen_binopvwmul_obj; +static CONSTEXPR const widen_binopvwaddu_obj; +static CONSTEXPR const widen_binopvwsubu_obj; +static CONSTEXPR const widen_binopvwmulu_obj; +static CONSTEXPR const vwmulsu vwmulsu_obj; +static CONSTEXPR const vwcvt vwcvt_x_obj; +static CONSTEXPR const vwcvt vwcvtu_x_obj; static CONSTEXPR const binop vsadd_obj; static CONSTEXPR const binop vssub_obj; static CONSTEXPR const binop vsaddu_obj; @@ -347,6 +413,15 @@ BASE (vneg) BASE (vnot) BASE (vsext) BASE (vzext) +BASE (vwadd) +BASE (vwsub) +BASE (vwmul) +BASE (vwaddu) +BASE (vwsubu) +BASE (vwmulu) +BASE (vwmulsu) +BASE (vwcvt_x) +BASE (vwcvtu_x) BASE (vsadd) BASE (vssub) BASE (vsaddu) diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h b/gcc/config/riscv/riscv-vector-builtins-bases.h index 96cfdd85659..51ec940a5aa 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.h +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h @@ -73,10 +73,20 @@ extern const function_base *const vneg; extern const function_base *const vnot; extern const function_base *const vsext; extern const function_base *const vzext; +extern const function_base *const vwadd; +extern const function_base *const vwsub; +extern const function_base *const vwmul; +extern const function_base *const vwaddu; +extern const function_base *const vwsubu; +extern const function_base *const vwmulu; +extern const function_base *const vwmulsu; +extern const function_base *const vwcvt_x; +extern const function_base *const vwcvtu_x; extern const function_base *const vsadd; extern const function_base *const vssub; extern const function_base *const vsaddu; extern const function_base *const vssubu; + } } // 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 418268f1279..e53fcb5546b 100644 --- a/gcc/config/riscv/riscv-vector-builtins-functions.def +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def @@ -112,6 +112,30 @@ DEF_RVV_FUNCTION (vsext, alu, full_preds, i_vf8_ops) DEF_RVV_FUNCTION (vzext, alu, full_preds, u_vf2_ops) DEF_RVV_FUNCTION (vzext, alu, full_preds, u_vf4_ops) DEF_RVV_FUNCTION (vzext, alu, full_preds, u_vf8_ops) +DEF_RVV_FUNCTION (vwadd, widen_alu, full_preds, i_wvv_ops) +DEF_RVV_FUNCTION (vwsub, widen_alu, full_preds, i_wvv_ops) +DEF_RVV_FUNCTION (vwmul, alu, full_preds, i_wvv_ops) +DEF_RVV_FUNCTION (vwmulu, alu, full_preds, u_wvv_ops) +DEF_RVV_FUNCTION (vwmulsu, alu, full_preds, i_su_wvv_ops) +DEF_RVV_FUNCTION (vwaddu, widen_alu, full_preds, u_wvv_ops) +DEF_RVV_FUNCTION (vwsubu, widen_alu, full_preds, u_wvv_ops) +DEF_RVV_FUNCTION (vwadd, widen_alu, full_preds, i_wvx_ops) +DEF_RVV_FUNCTION (vwsub, widen_alu, full_preds, i_wvx_ops) +DEF_RVV_FUNCTION (vwmul, alu, full_preds, i_wvx_ops) +DEF_RVV_FUNCTION (vwmulu, alu, full_preds, u_wvx_ops) +DEF_RVV_FUNCTION (vwmulsu, alu, full_preds, i_su_wvx_ops) +DEF_RVV_FUNCTION (vwaddu, widen_alu, full_preds, u_wvx_ops) +DEF_RVV_FUNCTION (vwsubu, widen_alu, full_preds, u_wvx_ops) +DEF_RVV_FUNCTION (vwadd, widen_alu, full_preds, i_wwv_ops) +DEF_RVV_FUNCTION (vwsub, widen_alu, full_preds, i_wwv_ops) +DEF_RVV_FUNCTION (vwaddu, widen_alu, full_preds, u_wwv_ops) +DEF_RVV_FUNCTION (vwsubu, widen_alu, full_preds, u_wwv_ops) +DEF_RVV_FUNCTION (vwadd, widen_alu, full_preds, i_wwx_ops) +DEF_RVV_FUNCTION (vwsub, widen_alu, full_preds, i_wwx_ops) +DEF_RVV_FUNCTION (vwaddu, widen_alu, full_preds, u_wwx_ops) +DEF_RVV_FUNCTION (vwsubu, widen_alu, full_preds, u_wwx_ops) +DEF_RVV_FUNCTION (vwcvt_x, alu, full_preds, i_x_x_v_ops) +DEF_RVV_FUNCTION (vwcvtu_x, alu, full_preds, u_x_x_v_ops) /* 12. Vector Fixed-Point Arithmetic Instructions. */ DEF_RVV_FUNCTION (vsadd, alu, full_preds, i_vvv_ops) DEF_RVV_FUNCTION (vssub, alu, full_preds, i_vvv_ops) diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc index e772a7ca475..62170f607ba 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc @@ -197,7 +197,8 @@ struct alu_def : public build_base API doesn't have OP suffix in overloaded function name, otherwise, we always append OP suffix in function name. For example, vsext_vf2. */ if (instance.op_info->op == OP_TYPE_vv || instance.op_info->op == OP_TYPE_vx - || instance.op_info->op == OP_TYPE_v) + || instance.op_info->op == OP_TYPE_v + || instance.op_info->op == OP_TYPE_x_v) { if (!overloaded_p) b.append_name (operand_suffixes[instance.op_info->op]); @@ -218,10 +219,37 @@ struct alu_def : public build_base } }; +/* widen_alu_def class. Handle vwadd/vwsub. Unlike + vadd.vx/vadd.vv/vwmul.vv/vwmul.vx, vwadd.vv/vwadd.vx/vwadd.wv/vwadd.wx has + 'OP' suffix in overloaded API. */ +struct widen_alu_def : public build_base +{ + char *get_name (function_builder &b, const function_instance &instance, + bool overloaded_p) const override + { + b.append_base_name (instance.base_name); + + /* vop --> vop_. */ + 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 (); + } +}; + SHAPE(vsetvl, vsetvl) SHAPE(vsetvl, vsetvlmax) SHAPE(loadstore, loadstore) SHAPE(indexed_loadstore, indexed_loadstore) SHAPE(alu, alu) +SHAPE(widen_alu, widen_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 b4f6eaa0bba..af5474ab36e 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.h +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h @@ -29,6 +29,7 @@ extern const function_shape *const vsetvlmax; extern const function_shape *const loadstore; extern const function_shape *const indexed_loadstore; extern const function_shape *const alu; +extern const function_shape *const widen_alu; } } // end namespace riscv_vector diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 696864ce76d..8462c8cdc7d 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -341,6 +341,43 @@ static CONSTEXPR const rvv_arg_type_info vector_size_args[] static CONSTEXPR const rvv_arg_type_info vf2_args[] = {rvv_arg_type_info (RVV_BASE_double_trunc_vector), rvv_arg_type_info_end}; +/* A list of args for vector_type func (double demote type, double demote type) + * function. */ +static CONSTEXPR const rvv_arg_type_info wvv_args[] + = {rvv_arg_type_info (RVV_BASE_double_trunc_vector), + rvv_arg_type_info (RVV_BASE_double_trunc_vector), rvv_arg_type_info_end}; + +/* A list of args for vector_type func (signed double demote type, + * unsigneddouble demote type) function. */ +static CONSTEXPR const rvv_arg_type_info su_wvv_args[] + = {rvv_arg_type_info (RVV_BASE_double_trunc_vector), + rvv_arg_type_info (RVV_BASE_double_trunc_unsigned_vector), rvv_arg_type_info_end}; + +/* A list of args for vector_type func (double demote type, double demote type) + * function. */ +static CONSTEXPR const rvv_arg_type_info wvx_args[] + = {rvv_arg_type_info (RVV_BASE_double_trunc_vector), + rvv_arg_type_info (RVV_BASE_double_trunc_scalar), rvv_arg_type_info_end}; + +/* A list of args for vector_type func (signed double demote type, unsigned + * double demote type) function. */ +static CONSTEXPR const rvv_arg_type_info su_wvx_args[] + = {rvv_arg_type_info (RVV_BASE_double_trunc_vector), + rvv_arg_type_info (RVV_BASE_double_trunc_unsigned_scalar), + rvv_arg_type_info_end}; + +/* A list of args for vector_type func (double demote type, double demote type) + * function. */ +static CONSTEXPR const rvv_arg_type_info wwv_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_double_trunc_vector), rvv_arg_type_info_end}; + +/* A list of args for vector_type func (double demote type, double demote type) + * function. */ +static CONSTEXPR const rvv_arg_type_info wwx_args[] + = {rvv_arg_type_info (RVV_BASE_vector), + rvv_arg_type_info (RVV_BASE_double_trunc_scalar), rvv_arg_type_info_end}; + /* A list of args for vector_type func (quad demote type) function. */ static CONSTEXPR const rvv_arg_type_info vf4_args[] = {rvv_arg_type_info (RVV_BASE_quad_trunc_vector), rvv_arg_type_info_end}; @@ -349,6 +386,10 @@ static CONSTEXPR const rvv_arg_type_info vf4_args[] static CONSTEXPR const rvv_arg_type_info vf8_args[] = {rvv_arg_type_info (RVV_BASE_oct_trunc_vector), rvv_arg_type_info_end}; +/* A list of args for vector_type func (double demote type) function. */ +static CONSTEXPR const rvv_arg_type_info x_x_v_args[] + = {rvv_arg_type_info (RVV_BASE_double_trunc_vector), rvv_arg_type_info_end}; + /* A list of none preds that will be registered for intrinsic functions. */ static CONSTEXPR const predication_type_index none_preds[] = {PRED_TYPE_none, NUM_PRED_TYPES}; @@ -658,6 +699,102 @@ static CONSTEXPR const rvv_op_info u_vf8_ops rvv_arg_type_info (RVV_BASE_vector), /* Return type */ vf8_args /* Args */}; +/* A static operand information for vector_type func (double demote type, double + * demote type) function registration. */ +static CONSTEXPR const rvv_op_info i_wvv_ops + = {wexti_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + wvv_args /* Args */}; + +/* A static operand information for vector_type func (signed double demote type, + * unsigned double demote type) function registration. */ +static CONSTEXPR const rvv_op_info i_su_wvv_ops + = {wexti_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + su_wvv_args /* Args */}; + +/* A static operand information for vector_type func (double demote type, double + * demote type) function registration. */ +static CONSTEXPR const rvv_op_info u_wvv_ops + = {wextu_ops, /* Types */ + OP_TYPE_vv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + wvv_args /* Args */}; + +/* A static operand information for vector_type func (double demote type, double + * demote scalar_type) function registration. */ +static CONSTEXPR const rvv_op_info i_wvx_ops + = {wexti_ops, /* Types */ + OP_TYPE_vx, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + wvx_args /* Args */}; + +/* A static operand information for vector_type func (signed double demote type, + * unsigned double demote scalar_type) function registration. */ +static CONSTEXPR const rvv_op_info i_su_wvx_ops + = {wexti_ops, /* Types */ + OP_TYPE_vx, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + su_wvx_args /* Args */}; + +/* A static operand information for vector_type func (vector_type, double + * demote type) function registration. */ +static CONSTEXPR const rvv_op_info i_wwv_ops + = {wexti_ops, /* Types */ + OP_TYPE_wv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + wwv_args /* Args */}; + +/* A static operand information for vector_type func (vector_type, double + * demote scalar_type) function registration. */ +static CONSTEXPR const rvv_op_info i_wwx_ops + = {wexti_ops, /* Types */ + OP_TYPE_wx, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + wwx_args /* Args */}; + +/* A static operand information for vector_type func (vector_type, double + * demote type) function registration. */ +static CONSTEXPR const rvv_op_info u_wwv_ops + = {wextu_ops, /* Types */ + OP_TYPE_wv, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + wwv_args /* Args */}; + +/* A static operand information for vector_type func (vector_type, double + * demote scalar_type) function registration. */ +static CONSTEXPR const rvv_op_info u_wwx_ops + = {wextu_ops, /* Types */ + OP_TYPE_wx, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + wwx_args /* Args */}; + +/* A static operand information for vector_type func (double demote type, double + * demote scalar_type) function registration. */ +static CONSTEXPR const rvv_op_info u_wvx_ops + = {wextu_ops, /* Types */ + OP_TYPE_vx, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + wvx_args /* Args */}; + +/* A static operand information for vector_type func (double demote type) + * function registration. */ +static CONSTEXPR const rvv_op_info i_x_x_v_ops + = {wexti_ops, /* Types */ + OP_TYPE_x_v, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + x_x_v_args /* Args */}; + +/* A static operand information for vector_type func (unsigned double demote + * type) function registration. */ +static CONSTEXPR const rvv_op_info u_x_x_v_ops + = {wextu_ops, /* Types */ + OP_TYPE_x_v, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + x_x_v_args /* Args */}; + /* A list of all RVV intrinsic functions. */ static function_group_info function_groups[] = { #define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO) \ @@ -944,6 +1081,9 @@ rvv_arg_type_info::get_base_vector_type (tree type) const poly_int64 nunits = GET_MODE_NUNITS (TYPE_MODE (type)); machine_mode inner_mode = GET_MODE_INNER (TYPE_MODE (type)); bool unsigned_p = TYPE_UNSIGNED (type); + if (base_type == RVV_BASE_double_trunc_unsigned_vector + || base_type == RVV_BASE_double_trunc_unsigned_scalar) + unsigned_p = true; switch (base_type) { case RVV_BASE_uint8_index: @@ -967,6 +1107,9 @@ rvv_arg_type_info::get_base_vector_type (tree type) const unsigned_p = true; break; case RVV_BASE_double_trunc_vector: + case RVV_BASE_double_trunc_scalar: + case RVV_BASE_double_trunc_unsigned_vector: + case RVV_BASE_double_trunc_unsigned_scalar: if (inner_mode == DImode) inner_mode = SImode; else if (inner_mode == SImode) @@ -1073,11 +1216,19 @@ rvv_arg_type_info::get_tree_type (vector_type_index type_idx) const case RVV_BASE_double_trunc_vector: case RVV_BASE_quad_trunc_vector: case RVV_BASE_oct_trunc_vector: + case RVV_BASE_double_trunc_unsigned_vector: if (get_base_vector_type (builtin_types[type_idx].vector) != NUM_VECTOR_TYPES) return builtin_types[get_base_vector_type ( builtin_types[type_idx].vector)].vector; break; + case RVV_BASE_double_trunc_scalar: + case RVV_BASE_double_trunc_unsigned_scalar: + if (get_base_vector_type (builtin_types[type_idx].vector) + != NUM_VECTOR_TYPES) + return builtin_types[get_base_vector_type ( + builtin_types[type_idx].vector)].scalar; + break; default: gcc_unreachable (); } diff --git a/gcc/config/riscv/riscv-vector-builtins.def b/gcc/config/riscv/riscv-vector-builtins.def index 89bd5f13995..9f4cd011404 100644 --- a/gcc/config/riscv/riscv-vector-builtins.def +++ b/gcc/config/riscv/riscv-vector-builtins.def @@ -273,7 +273,7 @@ DEF_RVV_OP_TYPE (vx) DEF_RVV_OP_TYPE (v) DEF_RVV_OP_TYPE (wv) DEF_RVV_OP_TYPE (wx) -DEF_RVV_OP_TYPE (x_x_v) +DEF_RVV_OP_TYPE (x_v) DEF_RVV_OP_TYPE (vf2) DEF_RVV_OP_TYPE (vf4) DEF_RVV_OP_TYPE (vf8) diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h index fc9d405784c..d033a2ea83f 100644 --- a/gcc/config/riscv/riscv-vector-builtins.h +++ b/gcc/config/riscv/riscv-vector-builtins.h @@ -158,6 +158,9 @@ enum rvv_base_type RVV_BASE_double_trunc_vector, RVV_BASE_quad_trunc_vector, RVV_BASE_oct_trunc_vector, + RVV_BASE_double_trunc_scalar, + RVV_BASE_double_trunc_unsigned_vector, + RVV_BASE_double_trunc_unsigned_scalar, NUM_BASE_TYPES }; diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index 8e6063ae83b..77c62e2d8f3 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -961,6 +961,46 @@ change_insn (function_info *ssa, insn_change change, insn_info *insn, /* These routines report failures themselves. */ if (!recog (attempt, change) || !change_is_worthwhile (change, false)) return false; + + /* Fix bug: + (insn 12 34 13 2 (set (reg:VNx8DI 120 v24 [orig:134 _1 ] [134]) + (if_then_else:VNx8DI (unspec:VNx8BI [ + (const_vector:VNx8BI repeat [ + (const_int 1 [0x1]) + ]) + (const_int 0 [0]) + (const_int 2 [0x2]) repeated x2 + (const_int 0 [0]) + (reg:SI 66 vl) + (reg:SI 67 vtype) + ] UNSPEC_VPREDICATE) + (plus:VNx8DI (reg/v:VNx8DI 104 v8 [orig:137 op1 ] [137]) + (sign_extend:VNx8DI (vec_duplicate:VNx8SI (reg:SI 15 a5 + [140])))) (unspec:VNx8DI [ (const_int 0 [0]) ] UNSPEC_VUNDEF))) "rvv.c":8:12 + 2784 {pred_single_widen_addsvnx8di_scalar} (expr_list:REG_EQUIV + (mem/c:VNx8DI (reg:DI 10 a0 [142]) [1 +0 S[64, 64] A128]) + (expr_list:REG_EQUAL (if_then_else:VNx8DI (unspec:VNx8BI [ + (const_vector:VNx8BI repeat [ + (const_int 1 [0x1]) + ]) + (reg/v:DI 13 a3 [orig:139 vl ] [139]) + (const_int 2 [0x2]) repeated x2 + (const_int 0 [0]) + (reg:SI 66 vl) + (reg:SI 67 vtype) + ] UNSPEC_VPREDICATE) + (plus:VNx8DI (reg/v:VNx8DI 104 v8 [orig:137 op1 ] [137]) + (const_vector:VNx8DI repeat [ + (const_int 2730 [0xaaa]) + ])) + (unspec:VNx8DI [ + (const_int 0 [0]) + ] UNSPEC_VUNDEF)) + (nil)))) + Here we want to remove use "a3". However, the REG_EQUAL/REG_EQUIV note use + "a3" which made us fail in change_insn. We reference to the + 'aarch64-cc-fusion.cc' and add this method. */ + remove_reg_equal_equiv_notes (rinsn); confirm_change_group (); ssa->change_insn (change); diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index daf30f5502d..ce401528511 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -651,9 +651,6 @@ enum reg_class #define FP_ARG_FIRST (FP_REG_FIRST + 10) #define FP_ARG_LAST (FP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1) -/* Helper macro for RVV vsetvl instruction generation. */ -#define X0_REGNUM GP_REG_FIRST - #define CALLEE_SAVED_REG_NUMBER(REGNO) \ ((REGNO) >= 8 && (REGNO) <= 9 ? (REGNO) - 8 : \ (REGNO) >= 18 && (REGNO) <= 27 ? (REGNO) - 16 : -1) diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 7f5de072215..cef9832d583 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -280,6 +280,9 @@ (define_code_iterator sat_int_plus_binop [ss_plus us_plus]) (define_code_iterator sat_int_minus_binop [ss_minus us_minus]) +(define_code_iterator any_widen_binop [plus minus mult]) +(define_code_iterator plus_minus [plus minus]) + (define_code_attr binop_rhs1_predicate [ (plus "register_operand") (minus "vector_arith_operand") @@ -391,6 +394,11 @@ (ss_minus "vsalu") (us_minus "vsalu")]) +(define_code_attr widen_binop_insn_type [ + (plus "walu") + (minus "walu") + (mult "wmul")]) + ;; expands to the insn name of binop matching constraint rhs1 is immediate. ;; minus is negated as vadd and ss_minus is negated as vsadd, others remain . (define_code_attr binop_vi_variant_insn [(ashift "sll.vi") diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 40a0bbea71a..ec177fa7efb 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -30,6 +30,7 @@ (define_constants [ (INVALID_ATTRIBUTE 255) + (X0_REGNUM 0) ]) ;; True if the type is RVV instructions that include VTYPE @@ -142,7 +143,7 @@ ;; It is valid for instruction that require sew/lmul ratio. (define_attr "ratio" "" (cond [(eq_attr "type" "vimov,vfmov,vldux,vldox,vstux,vstox,\ - vialu,vshift,vicmp,vimul,vidiv,vsalu,vext") + vialu,vshift,vicmp,vimul,vidiv,vsalu,vext,viwalu,viwmul") (const_int INVALID_ATTRIBUTE) (eq_attr "mode" "VNx1QI,VNx1BI") (symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)") @@ -193,7 +194,7 @@ ;; The index of operand[] to get the merge op. (define_attr "merge_op_idx" "" (cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu,vldux,vldox,\ - vialu,vshift,vicmp,vimul,vidiv,vsalu,vext") + vialu,vshift,vicmp,vimul,vidiv,vsalu,vext,viwalu,viwmul") (const_int 2)] (const_int INVALID_ATTRIBUTE))) @@ -210,7 +211,8 @@ (const_int 5) (const_int 4)) - (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu") + (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\ + viwalu,viwmul") (const_int 5)] (const_int INVALID_ATTRIBUTE))) @@ -226,7 +228,8 @@ (symbol_ref "riscv_vector::get_ta(operands[6])") (symbol_ref "riscv_vector::get_ta(operands[5])")) - (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu") + (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\ + viwalu,viwmul") (symbol_ref "riscv_vector::get_ta(operands[6])")] (const_int INVALID_ATTRIBUTE))) @@ -242,7 +245,8 @@ (symbol_ref "riscv_vector::get_ma(operands[7])") (symbol_ref "riscv_vector::get_ma(operands[6])")) - (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu") + (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\ + viwalu,viwmul") (symbol_ref "riscv_vector::get_ma(operands[7])")] (const_int INVALID_ATTRIBUTE))) @@ -260,7 +264,8 @@ (const_int INVALID_ATTRIBUTE) (symbol_ref "INTVAL (operands[7])")) - (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu") + (eq_attr "type" "vldux,vldox,vialu,vshift,vicmp,vimul,vidiv,vsalu,\ + viwalu,viwmul") (symbol_ref "INTVAL (operands[8])") (eq_attr "type" "vstux,vstox") (symbol_ref "INTVAL (operands[5])")] @@ -670,6 +675,26 @@ ;; (const_int:QI N)]), -15 <= N < 16. ;; 2. (const_vector:VNx1SF repeat [ ;; (const_double:SF 0.0 [0x0.0p+0])]). + +;; We add "MEM_P (operands[0]) || MEM_P (operands[3]) || CONST_VECTOR_P (operands[1])" here to +;; make sure we don't want CSE to generate the following pattern: +;; (insn 17 8 19 2 (set (reg:VNx1HI 134 [ _1 ]) +;; (if_then_else:VNx1HI (unspec:VNx1BI [ +;; (reg/v:VNx1BI 137 [ mask ]) +;; (reg:DI 151) +;; (const_int 0 [0]) repeated x3 +;; (reg:SI 66 vl) +;; (reg:SI 67 vtype) +;; ] UNSPEC_VPREDICATE) +;; (const_vector:VNx1HI repeat [ +;; (const_int 0 [0]) +;; ]) +;; (reg/v:VNx1HI 140 [ merge ]))) "rvv.c":8:12 608 {pred_movvnx1hi} +;; (expr_list:REG_DEAD (reg:DI 151) +;; (expr_list:REG_DEAD (reg/v:VNx1HI 140 [ merge ]) +;; (expr_list:REG_DEAD (reg/v:VNx1BI 137 [ mask ]) +;; (nil))))) +;; Since both vmv.v.v and vmv.v.i doesn't have mask operand. (define_insn_and_split "@pred_mov" [(set (match_operand:V 0 "nonimmediate_operand" "=vr, vr, vd, m, vr, vr") (if_then_else:V @@ -683,7 +708,8 @@ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) (match_operand:V 3 "vector_move_operand" " m, m, m, vr, vr, viWc0") (match_operand:V 2 "vector_merge_operand" " 0, vu, vu, vu, vu0, vu0")))] - "TARGET_VECTOR" + "TARGET_VECTOR && (MEM_P (operands[0]) || MEM_P (operands[3]) + || CONST_VECTOR_P (operands[1]))" "@ vle.v\t%0,%3%p1 vle.v\t%0,%3 @@ -1930,14 +1956,16 @@ (set_attr "mode" "") (set_attr "vl_op_idx" "4") (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])")) - (set (attr "ma") (symbol_ref "riscv_vector::get_ta(operands[6])")) + (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])")) (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))]) ;; ------------------------------------------------------------------------------- ;; ---- Predicated integer widening operations ;; ------------------------------------------------------------------------------- ;; Includes: +;; - 11.2 Vector Widening Integer Add/Subtract ;; - 11.3 Vector Integer Extension +;; - 11.12 Vector Widening Integer Multiply Instructions ;; ------------------------------------------------------------------------------- ;; Vector Double-Widening Sign-extend and Zero-extend. @@ -1999,3 +2027,164 @@ "vext.vf8\t%0,%3%p1" [(set_attr "type" "vext") (set_attr "mode" "")]) + +;; Vector Widening Add/Subtract/Multiply. +(define_insn "@pred_dual_widen_" + [(set (match_operand:VWEXTI 0 "register_operand" "=&vr") + (if_then_else:VWEXTI + (unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1") + (match_operand 5 "vector_length_operand" " rK") + (match_operand 6 "const_int_operand" " i") + (match_operand 7 "const_int_operand" " i") + (match_operand 8 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (any_widen_binop:VWEXTI + (any_extend:VWEXTI + (match_operand: 3 "register_operand" " vr")) + (any_extend:VWEXTI + (match_operand: 4 "register_operand" " vr"))) + (match_operand:VWEXTI 2 "vector_merge_operand" " 0vu")))] + "TARGET_VECTOR" + "vw.vv\t%0,%3,%4%p1" + [(set_attr "type" "vi") + (set_attr "mode" "")]) + +(define_insn "@pred_dual_widen__scalar" + [(set (match_operand:VWEXTI 0 "register_operand" "=&vr") + (if_then_else:VWEXTI + (unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1") + (match_operand 5 "vector_length_operand" " rK") + (match_operand 6 "const_int_operand" " i") + (match_operand 7 "const_int_operand" " i") + (match_operand 8 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (any_widen_binop:VWEXTI + (any_extend:VWEXTI + (match_operand: 3 "register_operand" " vr")) + (any_extend:VWEXTI + (vec_duplicate: + (match_operand: 4 "reg_or_0_operand" " rJ")))) + (match_operand:VWEXTI 2 "vector_merge_operand" " 0vu")))] + "TARGET_VECTOR" + "vw.vx\t%0,%3,%z4%p1" + [(set_attr "type" "vi") + (set_attr "mode" "")]) + +(define_insn "@pred_single_widen_" + [(set (match_operand:VWEXTI 0 "register_operand" "=&vr") + (if_then_else:VWEXTI + (unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1") + (match_operand 5 "vector_length_operand" " rK") + (match_operand 6 "const_int_operand" " i") + (match_operand 7 "const_int_operand" " i") + (match_operand 8 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (plus_minus:VWEXTI + (match_operand:VWEXTI 3 "register_operand" " vr") + (any_extend:VWEXTI + (match_operand: 4 "register_operand" " vr"))) + (match_operand:VWEXTI 2 "vector_merge_operand" " 0vu")))] + "TARGET_VECTOR" + "vw.wv\t%0,%3,%4%p1" + [(set_attr "type" "vi") + (set_attr "mode" "")]) + +(define_insn "@pred_single_widen__scalar" + [(set (match_operand:VWEXTI 0 "register_operand" "=&vr") + (if_then_else:VWEXTI + (unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1") + (match_operand 5 "vector_length_operand" " rK") + (match_operand 6 "const_int_operand" " i") + (match_operand 7 "const_int_operand" " i") + (match_operand 8 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (plus_minus:VWEXTI + (match_operand:VWEXTI 3 "register_operand" " vr") + (any_extend:VWEXTI + (vec_duplicate: + (match_operand: 4 "reg_or_0_operand" " rJ")))) + (match_operand:VWEXTI 2 "vector_merge_operand" " 0vu")))] + "TARGET_VECTOR" + "vw.wx\t%0,%3,%z4%p1" + [(set_attr "type" "vi") + (set_attr "mode" "")]) + +(define_insn "@pred_widen_mulsu" + [(set (match_operand:VWEXTI 0 "register_operand" "=&vr") + (if_then_else:VWEXTI + (unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1") + (match_operand 5 "vector_length_operand" " rK") + (match_operand 6 "const_int_operand" " i") + (match_operand 7 "const_int_operand" " i") + (match_operand 8 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (mult:VWEXTI + (sign_extend:VWEXTI + (match_operand: 3 "register_operand" " vr")) + (zero_extend:VWEXTI + (match_operand: 4 "register_operand" " vr"))) + (match_operand:VWEXTI 2 "vector_merge_operand" " 0vu")))] + "TARGET_VECTOR" + "vwmulsu.vv\t%0,%3,%4%p1" + [(set_attr "type" "viwmul") + (set_attr "mode" "")]) + +(define_insn "@pred_widen_mulsu_scalar" + [(set (match_operand:VWEXTI 0 "register_operand" "=&vr") + (if_then_else:VWEXTI + (unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1") + (match_operand 5 "vector_length_operand" " rK") + (match_operand 6 "const_int_operand" " i") + (match_operand 7 "const_int_operand" " i") + (match_operand 8 "const_int_operand" " i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (mult:VWEXTI + (sign_extend:VWEXTI + (match_operand: 3 "register_operand" " vr")) + (zero_extend:VWEXTI + (vec_duplicate: + (match_operand: 4 "reg_or_0_operand" " rJ")))) + (match_operand:VWEXTI 2 "vector_merge_operand" " 0vu")))] + "TARGET_VECTOR" + "vwmulsu.vx\t%0,%3,%z4%p1" + [(set_attr "type" "viwmul") + (set_attr "mode" "")]) + +;; vwcvt.x.x.v +(define_insn "@pred_" + [(set (match_operand:VWEXTI 0 "register_operand" "=&vr") + (if_then_else:VWEXTI + (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) + (plus:VWEXTI + (any_extend:VWEXTI + (match_operand: 3 "register_operand" " vr")) + (vec_duplicate:VWEXTI + (reg: X0_REGNUM))) + (match_operand:VWEXTI 2 "vector_merge_operand" " 0vu")))] + "TARGET_VECTOR" + "vwcvt.x.x.v\t%0,%3%p1" + [(set_attr "type" "viwalu") + (set_attr "mode" "") + (set_attr "vl_op_idx" "4") + (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])")) + (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])")) + (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])