From patchwork Fri Dec 23 00:52:46 2022 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: 36027 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:e747:0:0:0:0:0 with SMTP id c7csp67850wrn; Thu, 22 Dec 2022 16:53:46 -0800 (PST) X-Google-Smtp-Source: AMrXdXts62Zrrn8sWFyUOnVkAF93ledSrqXKaonA+OkkLVMU+QrUT2oafY1dmosD5ovDq6legfyg X-Received: by 2002:a05:6402:2b89:b0:461:ca30:653 with SMTP id fj9-20020a0564022b8900b00461ca300653mr7939824edb.31.1671756825871; Thu, 22 Dec 2022 16:53:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1671756825; cv=none; d=google.com; s=arc-20160816; b=pLsqqOQ1MPfejS3x0cS+dukKD5EsZbM8zPLt11okS+8E1hDs2GzruYkHOcEvdMlW+P 45UUGySl6e0R0BqFqXbPQ6qS5aMy8h0AUuoXOCbIDL3o9sFA+YHo1H7LRHsrXRLh6de1 lwmDZiPveoyFr1ZWzYPsXi4FrXppWZrkQ7tp36QfHkYSzjM7OUFzb8lDtMcl/+tL8qxG OAl/vWccvnGpd1jNGKDDOVhAy+aV0OtiTPErNM2YRtJgszrBVKUbru2xi8zb21vIerir my0m/ziC4LWOkEipMyLCNtm+0oazKMOrA2+wYzTaSIq72tHN3i/SXX1z38qmbDIuZuvp qG2Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:feedback-id :content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:dmarc-filter:delivered-to; bh=ggBqIPOJo7Wus8A92vPuD0/z/fclDJEfcRU77GLjjdA=; b=mKhYzgIMpznsiLHqJhm2wDD1EHSdsnx9d4+9qMnyHN9l8/aNaviV8+Dk0gALeHcy3n sbDTK9qrX7bkIPAM290V4fSRFDZsd13xXniVwtESzXJQE3wBl/6DjiqFabLwNsdUqxmk G0j3NftCYLNvH2bm8sArDQKkdUm0y328Mgg43Q8GmcO2SptYAv5q3bpOeEOBtXyyO/0u AT3J1n6kdjokJ3yg97FRfoh5ESEfmeahVcvnzwa+Af33JhVka9mdILwHbhf/z5jBIEtV XangtvZOBPQiROhLGaSa0JBoTXE5WPHx5TpC4anpXZZsBPSR74xA7vlPjVFEEzMTYkSt 8gJQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id k7-20020a05640212c700b00458bbd3a0d2si1550339edx.602.2022.12.22.16.53.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Dec 2022 16:53:45 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E1EB1385B511 for ; Fri, 23 Dec 2022 00:53:39 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtpbguseast3.qq.com (smtpbguseast3.qq.com [54.243.244.52]) by sourceware.org (Postfix) with ESMTPS id 1FD5B3858D1E for ; Fri, 23 Dec 2022 00:52:56 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1FD5B3858D1E 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: bizesmtp64t1671756770tmf4vfgn Received: from rios-cad5.localdomain ( [58.60.1.11]) by bizesmtp.qq.com (ESMTP) with id ; Fri, 23 Dec 2022 08:52:49 +0800 (CST) X-QQ-SSF: 01400000000000E0L000000A0000000 X-QQ-FEAT: NV69rQnjVY5P+g+7tnF9BxaDnl70wjJ12ptbpLZtSqdEfCiYIxYkSPZ+IxyKQ J1F/M6R1ojcsxuvAGfeF3MmhsXxP6BjIDLmqr/xVEdSVP1YvQxcXDWGN397xnhEJFNNVPt6 wmfeNUbH6PaHpewMJheD4J0ScRgefoYaBbaiuVFKurteK58iIG3YeI7icnSAz4bnF6p7Jbd uNhaKU8a1XyNGp4vnecV2H+E2R7NZqGQC0//w4UtBQ/0SI8FRDcEOiqvZ+quQPxEzO4qdP7 /p1Tt6vHCMMlWaZKXcLzHaomlYNoT+U9T9dbJLOc99mOJnKBp3WLtf26Iizb9iPkNoQJhxi Auc6TUD4dNi3YMJb4DZs/T2X9XesjRhXrtaRe3f5pazbp9GREg= X-QQ-GoodBg: 2 From: juzhe.zhong@rivai.ai To: gcc-patches@gcc.gnu.org Cc: kito.cheng@gmail.com, palmer@dabbelt.com, Ju-Zhe Zhong Subject: [PATCH] RISC-V: Support vle.v/vse.v intrinsics Date: Fri, 23 Dec 2022 08:52:46 +0800 Message-Id: <20221223005246.38622-1-juzhe.zhong@rivai.ai> X-Mailer: git-send-email 2.36.3 MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:rivai.ai:qybglogicsvr:qybglogicsvr7 X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, 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+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1752964085566523910?= X-GMAIL-MSGID: =?utf-8?q?1752964085566523910?= From: Ju-Zhe Zhong gcc/ChangeLog: * config/riscv/riscv-protos.h (get_avl_type_rtx): New function. * config/riscv/riscv-v.cc (get_avl_type_rtx): Ditto. * config/riscv/riscv-vector-builtins-bases.cc (class loadstore): New class. (BASE): Ditto. * config/riscv/riscv-vector-builtins-bases.h: Ditto. * config/riscv/riscv-vector-builtins-functions.def (vle): Ditto. (vse): Ditto. * config/riscv/riscv-vector-builtins-shapes.cc (build_one): Ditto. (struct loadstore_def): Ditto. (SHAPE): Ditto. * config/riscv/riscv-vector-builtins-shapes.h: Ditto. * config/riscv/riscv-vector-builtins-types.def (DEF_RVV_U_OPS): New macro. (DEF_RVV_F_OPS): Ditto. (vuint8mf8_t): Add corresponding mask type. (vuint8mf4_t): Ditto. (vuint8mf2_t): Ditto. (vuint8m1_t): Ditto. (vuint8m2_t): Ditto. (vuint8m4_t): Ditto. (vuint8m8_t): Ditto. (vuint16mf4_t): Ditto. (vuint16mf2_t): Ditto. (vuint16m1_t): Ditto. (vuint16m2_t): Ditto. (vuint16m4_t): Ditto. (vuint16m8_t): Ditto. (vuint32mf2_t): Ditto. (vuint32m1_t): Ditto. (vuint32m2_t): Ditto. (vuint32m4_t): Ditto. (vuint32m8_t): Ditto. (vuint64m1_t): Ditto. (vuint64m2_t): Ditto. (vuint64m4_t): Ditto. (vuint64m8_t): Ditto. (vfloat32mf2_t): Ditto. (vfloat32m1_t): Ditto. (vfloat32m2_t): Ditto. (vfloat32m4_t): Ditto. (vfloat32m8_t): Ditto. (vfloat64m1_t): Ditto. (vfloat64m2_t): Ditto. (vfloat64m4_t): Ditto. (vfloat64m8_t): Ditto. * config/riscv/riscv-vector-builtins.cc (DEF_RVV_TYPE): Adjust for new macro. (DEF_RVV_I_OPS): Ditto. (DEF_RVV_U_OPS): New macro. (DEF_RVV_F_OPS): New macro. (use_real_mask_p): New function. (use_real_merge_p): Ditto. (get_tail_policy_for_pred): Ditto. (get_mask_policy_for_pred): Ditto. (function_builder::apply_predication): Ditto. (function_builder::append_base_name): Ditto. (function_builder::append_sew): Ditto. (function_expander::add_vundef_operand): Ditto. (function_expander::add_mem_operand): Ditto. (function_expander::use_contiguous_load_insn): Ditto. (function_expander::use_contiguous_store_insn): Ditto. * config/riscv/riscv-vector-builtins.def (DEF_RVV_TYPE): Adjust for adding mask type. (vbool64_t): Ditto. (vbool32_t): Ditto. (vbool16_t): Ditto. (vbool8_t): Ditto. (vbool4_t): Ditto. (vbool2_t): Ditto. (vbool1_t): Ditto. (vint8mf8_t): Ditto. (vint8mf4_t): Ditto. (vint8mf2_t): Ditto. (vint8m1_t): Ditto. (vint8m2_t): Ditto. (vint8m4_t): Ditto. (vint8m8_t): Ditto. (vint16mf4_t): Ditto. (vint16mf2_t): Ditto. (vint16m1_t): Ditto. (vint16m2_t): Ditto. (vint16m4_t): Ditto. (vint16m8_t): Ditto. (vint32mf2_t): Ditto. (vint32m1_t): Ditto. (vint32m2_t): Ditto. (vint32m4_t): Ditto. (vint32m8_t): Ditto. (vint64m1_t): Ditto. (vint64m2_t): Ditto. (vint64m4_t): Ditto. (vint64m8_t): Ditto. (vfloat32mf2_t): Ditto. (vfloat32m1_t): Ditto. (vfloat32m2_t): Ditto. (vfloat32m4_t): Ditto. (vfloat32m8_t): Ditto. (vfloat64m1_t): Ditto. (vfloat64m4_t): Ditto. * config/riscv/riscv-vector-builtins.h (function_expander::add_output_operand): New function. (function_expander::add_all_one_mask_operand): Ditto. (function_expander::add_fixed_operand): Ditto. (function_expander::vector_mode): Ditto. (function_base::apply_vl_p): Ditto. (function_base::can_be_overloaded_p): Ditto. * config/riscv/riscv-vsetvl.cc (get_vl): Remove restrict of supporting AVL is not VLMAX. * config/riscv/t-riscv: Add include file. --- gcc/config/riscv/riscv-protos.h | 1 + gcc/config/riscv/riscv-v.cc | 10 +- .../riscv/riscv-vector-builtins-bases.cc | 49 +++- .../riscv/riscv-vector-builtins-bases.h | 2 + .../riscv/riscv-vector-builtins-functions.def | 3 + .../riscv/riscv-vector-builtins-shapes.cc | 38 ++- .../riscv/riscv-vector-builtins-shapes.h | 1 + .../riscv/riscv-vector-builtins-types.def | 49 +++- gcc/config/riscv/riscv-vector-builtins.cc | 236 +++++++++++++++++- gcc/config/riscv/riscv-vector-builtins.def | 122 ++++----- gcc/config/riscv/riscv-vector-builtins.h | 65 +++++ gcc/config/riscv/riscv-vsetvl.cc | 4 - gcc/config/riscv/t-riscv | 2 +- 13 files changed, 506 insertions(+), 76 deletions(-) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index cfd0f284f91..64ee56b8a7c 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -171,6 +171,7 @@ enum mask_policy }; enum tail_policy get_prefer_tail_policy (); enum mask_policy get_prefer_mask_policy (); +rtx get_avl_type_rtx (enum avl_type); } /* We classify builtin types into two classes: diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index f02a048f76d..b616ee3e6b3 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -79,8 +79,7 @@ public: } void add_avl_type_operand () { - rtx vlmax_rtx = gen_int_mode (avl_type::VLMAX, Pmode); - add_input_operand (vlmax_rtx, Pmode); + add_input_operand (get_avl_type_rtx (avl_type::VLMAX), Pmode); } void expand (enum insn_code icode, bool temporary_volatile_p = false) @@ -342,4 +341,11 @@ get_prefer_mask_policy () return MASK_ANY; } +/* Get avl_type rtx. */ +rtx +get_avl_type_rtx (enum avl_type type) +{ + return gen_int_mode (type, Pmode); +} + } // namespace riscv_vector diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index c1193dbbfb5..10373e5ccf2 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -53,6 +53,11 @@ template class vsetvl : public function_base { public: + bool apply_vl_p () const override + { + return false; + } + rtx expand (function_expander &e) const override { if (VLMAX_P) @@ -79,11 +84,47 @@ public: } }; +/* Implements vle.v/vse.v codegen. */ +template +class loadstore : public function_base +{ + unsigned int call_properties (const function_instance &) const override + { + if (STORE_P) + return CP_WRITE_MEMORY; + else + return CP_READ_MEMORY; + } + + bool can_be_overloaded_p (enum predication_type_index pred) const override + { + if (STORE_P) + return true; + return pred != PRED_TYPE_none && pred != PRED_TYPE_mu; + } + + rtx expand (function_expander &e) const override + { + if (STORE_P) + return e.use_contiguous_store_insn (code_for_pred_mov (e.vector_mode ())); + else + return e.use_contiguous_load_insn (code_for_pred_mov (e.vector_mode ())); + } +}; + static CONSTEXPR const vsetvl vsetvl_obj; static CONSTEXPR const vsetvl vsetvlmax_obj; -namespace bases { -const function_base *const vsetvl = &vsetvl_obj; -const function_base *const vsetvlmax = &vsetvlmax_obj; -} +static CONSTEXPR const loadstore vle_obj; +static CONSTEXPR const loadstore vse_obj; + +/* Declare the function base NAME, pointing it to an instance + of class _obj. */ +#define BASE(NAME) \ + namespace bases { const function_base *const NAME = &NAME##_obj; } + +BASE (vsetvl) +BASE (vsetvlmax) +BASE (vle) +BASE (vse) } // 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 a0ae18eef03..79684bcb50d 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.h +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h @@ -26,6 +26,8 @@ namespace riscv_vector { namespace bases { extern const function_base *const vsetvl; extern const function_base *const vsetvlmax; +extern const function_base *const vle; +extern const function_base *const vse; } } // 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 dc41537865e..e5ebb7d829c 100644 --- a/gcc/config/riscv/riscv-vector-builtins-functions.def +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def @@ -39,5 +39,8 @@ along with GCC; see the file COPYING3. If not see /* 6. Configuration-Setting Instructions. */ DEF_RVV_FUNCTION (vsetvl, vsetvl, none_preds, i_none_size_size_ops) DEF_RVV_FUNCTION (vsetvlmax, vsetvlmax, none_preds, i_none_size_void_ops) +/* 7. Vector Loads and Stores. */ +DEF_RVV_FUNCTION (vle, loadstore, full_preds, all_v_scalar_const_ptr_ops) +DEF_RVV_FUNCTION (vse, loadstore, none_m_preds, all_v_scalar_ptr_ops) #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 bb2ee8767a0..0332c031ce4 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc @@ -48,6 +48,7 @@ build_one (function_builder &b, const function_group_info &group, tree return_type = group.ops_infos.ret.get_tree_type ( group.ops_infos.types[vec_type_idx].index); b.allocate_argument_types (function_instance, argument_types); + b.apply_predication (function_instance, return_type, argument_types); b.add_unique_function (function_instance, (*group.shape), return_type, argument_types); } @@ -93,13 +94,46 @@ struct vsetvl_def : public build_base /* vsetvl* instruction doesn't have C++ overloaded functions. */ if (overloaded_p) return nullptr; - b.append_name ("__riscv_"); - b.append_name (instance.base_name); + b.append_base_name (instance.base_name); b.append_name (type_suffixes[instance.type.index].vsetvl); return b.finish_name (); } }; + +/* loadstore_def class. */ +struct loadstore_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); + + tree type = builtin_types[instance.type.index].vector; + machine_mode mode = TYPE_MODE (type); + int sew = GET_MODE_BITSIZE (GET_MODE_INNER (mode)); + /* vop --> vop. */ + b.append_sew (sew); + + /* vop_v --> vop_v_. */ + if (!overloaded_p) + { + /* vop --> vop_v. */ + b.append_name (operand_suffixes[instance.op_info->op]); + /* vop_v --> vop_v_. */ + b.append_name (type_suffixes[instance.type.index].vector); + } + + b.append_name (predication_suffixes[instance.pred]); + return b.finish_name (); + } +}; + SHAPE(vsetvl, vsetvl) SHAPE(vsetvl, vsetvlmax) +SHAPE(loadstore, loadstore) } // 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 f2d876fb133..b17dcd88877 100644 --- a/gcc/config/riscv/riscv-vector-builtins-shapes.h +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h @@ -26,6 +26,7 @@ namespace riscv_vector { namespace shapes { extern const function_shape *const vsetvl; extern const function_shape *const vsetvlmax; +extern const function_shape *const loadstore; } } // end namespace riscv_vector diff --git a/gcc/config/riscv/riscv-vector-builtins-types.def b/gcc/config/riscv/riscv-vector-builtins-types.def index f282a5e7654..6a867c99987 100644 --- a/gcc/config/riscv/riscv-vector-builtins-types.def +++ b/gcc/config/riscv/riscv-vector-builtins-types.def @@ -18,12 +18,24 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ -/* Use "DEF_ALL_SIGNED_INTEGER" macro include all signed integer which will be +/* Use "DEF_RVV_I_OPS" macro include all signed integer which will be iterated and registered as intrinsic functions. */ #ifndef DEF_RVV_I_OPS #define DEF_RVV_I_OPS(TYPE, REQUIRE) #endif +/* Use "DEF_RVV_U_OPS" macro include all unsigned integer which will be + iterated and registered as intrinsic functions. */ +#ifndef DEF_RVV_U_OPS +#define DEF_RVV_U_OPS(TYPE, REQUIRE) +#endif + +/* Use "DEF_RVV_F_OPS" macro include all floating-point which will be + iterated and registered as intrinsic functions. */ +#ifndef DEF_RVV_F_OPS +#define DEF_RVV_F_OPS(TYPE, REQUIRE) +#endif + DEF_RVV_I_OPS (vint8mf8_t, RVV_REQUIRE_ZVE64) DEF_RVV_I_OPS (vint8mf4_t, 0) DEF_RVV_I_OPS (vint8mf2_t, 0) @@ -47,4 +59,39 @@ DEF_RVV_I_OPS (vint64m2_t, RVV_REQUIRE_ZVE64) DEF_RVV_I_OPS (vint64m4_t, RVV_REQUIRE_ZVE64) DEF_RVV_I_OPS (vint64m8_t, RVV_REQUIRE_ZVE64) +DEF_RVV_U_OPS (vuint8mf8_t, RVV_REQUIRE_ZVE64) +DEF_RVV_U_OPS (vuint8mf4_t, 0) +DEF_RVV_U_OPS (vuint8mf2_t, 0) +DEF_RVV_U_OPS (vuint8m1_t, 0) +DEF_RVV_U_OPS (vuint8m2_t, 0) +DEF_RVV_U_OPS (vuint8m4_t, 0) +DEF_RVV_U_OPS (vuint8m8_t, 0) +DEF_RVV_U_OPS (vuint16mf4_t, RVV_REQUIRE_ZVE64) +DEF_RVV_U_OPS (vuint16mf2_t, 0) +DEF_RVV_U_OPS (vuint16m1_t, 0) +DEF_RVV_U_OPS (vuint16m2_t, 0) +DEF_RVV_U_OPS (vuint16m4_t, 0) +DEF_RVV_U_OPS (vuint16m8_t, 0) +DEF_RVV_U_OPS (vuint32mf2_t, RVV_REQUIRE_ZVE64) +DEF_RVV_U_OPS (vuint32m1_t, 0) +DEF_RVV_U_OPS (vuint32m2_t, 0) +DEF_RVV_U_OPS (vuint32m4_t, 0) +DEF_RVV_U_OPS (vuint32m8_t, 0) +DEF_RVV_U_OPS (vuint64m1_t, RVV_REQUIRE_ZVE64) +DEF_RVV_U_OPS (vuint64m2_t, RVV_REQUIRE_ZVE64) +DEF_RVV_U_OPS (vuint64m4_t, RVV_REQUIRE_ZVE64) +DEF_RVV_U_OPS (vuint64m8_t, RVV_REQUIRE_ZVE64) + +DEF_RVV_F_OPS (vfloat32mf2_t, RVV_REQUIRE_ELEN_FP_32 | RVV_REQUIRE_ZVE64) +DEF_RVV_F_OPS (vfloat32m1_t, RVV_REQUIRE_ELEN_FP_32) +DEF_RVV_F_OPS (vfloat32m2_t, RVV_REQUIRE_ELEN_FP_32) +DEF_RVV_F_OPS (vfloat32m4_t, RVV_REQUIRE_ELEN_FP_32) +DEF_RVV_F_OPS (vfloat32m8_t, RVV_REQUIRE_ELEN_FP_32) +DEF_RVV_F_OPS (vfloat64m1_t, RVV_REQUIRE_ELEN_FP_64) +DEF_RVV_F_OPS (vfloat64m2_t, RVV_REQUIRE_ELEN_FP_64) +DEF_RVV_F_OPS (vfloat64m4_t, RVV_REQUIRE_ELEN_FP_64) +DEF_RVV_F_OPS (vfloat64m8_t, RVV_REQUIRE_ELEN_FP_64) + #undef DEF_RVV_I_OPS +#undef DEF_RVV_U_OPS +#undef DEF_RVV_F_OPS diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 43150aa47a4..9170776f979 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -44,6 +44,7 @@ #include "attribs.h" #include "targhooks.h" #include "regs.h" +#include "emit-rtl.h" #include "riscv-vector-builtins.h" #include "riscv-vector-builtins-shapes.h" #include "riscv-vector-builtins-bases.h" @@ -105,11 +106,20 @@ const char *const operand_suffixes[NUM_OP_TYPES] = { const rvv_builtin_suffixes type_suffixes[NUM_VECTOR_TYPES + 1] = { #define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, SCALAR_TYPE, VECTOR_MODE, \ VECTOR_MODE_MIN_VLEN_32, VECTOR_SUFFIX, SCALAR_SUFFIX, \ - VSETVL_SUFFIX) \ + VSETVL_SUFFIX, MASK_TYPE) \ {#VECTOR_SUFFIX, #SCALAR_SUFFIX, #VSETVL_SUFFIX}, #include "riscv-vector-builtins.def" }; +/* Mask type for each RVV type. */ +const vector_type_index mask_types[NUM_VECTOR_TYPES + 1] = { +#define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, SCALAR_TYPE, VECTOR_MODE, \ + VECTOR_MODE_MIN_VLEN_32, VECTOR_SUFFIX, SCALAR_SUFFIX, \ + VSETVL_SUFFIX, MASK_TYPE) \ + VECTOR_TYPE_##MASK_TYPE, +#include "riscv-vector-builtins.def" +}; + /* Static information about predication suffix for each RVV type. */ const char *const predication_suffixes[NUM_PRED_TYPES] = { "", /* PRED_TYPE_none. */ @@ -123,6 +133,14 @@ static const rvv_type_info i_ops[] = { #include "riscv-vector-builtins-types.def" {NUM_VECTOR_TYPES, 0}}; +/* A list of all types will be registered for intrinsic functions. */ +static const rvv_type_info all_ops[] = { +#define DEF_RVV_I_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE}, +#define DEF_RVV_U_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE}, +#define DEF_RVV_F_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE}, +#include "riscv-vector-builtins-types.def" + {NUM_VECTOR_TYPES, 0}}; + static CONSTEXPR const rvv_arg_type_info rvv_arg_type_info_end = rvv_arg_type_info (NUM_BASE_TYPES); @@ -134,10 +152,28 @@ static CONSTEXPR const rvv_arg_type_info void_args[] static CONSTEXPR const rvv_arg_type_info size_args[] = {rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end}; +/* A list of args for vector_type func (const scalar_type *) function. */ +static CONSTEXPR const rvv_arg_type_info scalar_const_ptr_args[] + = {rvv_arg_type_info (RVV_BASE_scalar_const_ptr), rvv_arg_type_info_end}; + +/* A list of args for void func (scalar_type *, vector_type) function. */ +static CONSTEXPR const rvv_arg_type_info scalar_ptr_args[] + = {rvv_arg_type_info (RVV_BASE_scalar_const_ptr), + rvv_arg_type_info (RVV_BASE_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}; +/* vop/vop_m/vop_tu/vop_tum/vop_tumu/vop_mu will be registered. */ +static CONSTEXPR const predication_type_index full_preds[] + = {PRED_TYPE_none, PRED_TYPE_m, PRED_TYPE_tu, PRED_TYPE_tum, + PRED_TYPE_tumu, PRED_TYPE_mu, NUM_PRED_TYPES}; + +/* vop/vop_m will be registered. */ +static CONSTEXPR const predication_type_index none_m_preds[] + = {PRED_TYPE_none, PRED_TYPE_m, NUM_PRED_TYPES}; + /* A static operand information for size_t func (void) function registration. */ static CONSTEXPR const rvv_op_info i_none_size_void_ops = {i_ops, /* Types */ @@ -153,6 +189,22 @@ static CONSTEXPR const rvv_op_info i_none_size_size_ops rvv_arg_type_info (RVV_BASE_size), /* Return type */ size_args /* Args */}; +/* A static operand information for vector_type func (const scalar_type *) + * function registration. */ +static CONSTEXPR const rvv_op_info all_v_scalar_const_ptr_ops + = {all_ops, /* Types */ + OP_TYPE_v, /* Suffix */ + rvv_arg_type_info (RVV_BASE_vector), /* Return type */ + scalar_const_ptr_args /* Args */}; + +/* A static operand information for void func (scalar_type *, vector_type) + * function registration. */ +static CONSTEXPR const rvv_op_info all_v_scalar_ptr_ops + = {all_ops, /* Types */ + OP_TYPE_v, /* Suffix */ + rvv_arg_type_info (RVV_BASE_void), /* Return type */ + scalar_ptr_args /* Args */}; + /* A list of all RVV intrinsic functions. */ static function_group_info function_groups[] = { #define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO) \ @@ -362,6 +414,42 @@ check_required_extensions (uint64_t required_extensions) return true; } +/* Return true if predication is using a real mask operand. */ +static bool +use_real_mask_p (enum predication_type_index pred) +{ + return pred == PRED_TYPE_m || pred == PRED_TYPE_tum || pred == PRED_TYPE_tumu + || pred == PRED_TYPE_mu; +} + +/* Return true if predication is using a real merge operand. */ +static bool +use_real_merge_p (enum predication_type_index pred) +{ + return pred == PRED_TYPE_tu || pred == PRED_TYPE_tum || pred == PRED_TYPE_tumu + || pred == PRED_TYPE_mu; +} + +/* Get TAIL policy for predication. If predication indicates TU, return the TU. + Otherwise, return the prefer default configuration. */ +static rtx +get_tail_policy_for_pred (enum predication_type_index pred) +{ + if (pred == PRED_TYPE_tu || pred == PRED_TYPE_tum || pred == PRED_TYPE_tumu) + return gen_int_mode (TAIL_UNDISTURBED, Pmode); + return gen_int_mode (get_prefer_tail_policy (), Pmode); +} + +/* Get MASK policy for predication. If predication indicates MU, return the MU. + Otherwise, return the prefer default configuration. */ +static rtx +get_mask_policy_for_pred (enum predication_type_index pred) +{ + if (pred == PRED_TYPE_tumu || pred == PRED_TYPE_mu) + return gen_int_mode (MASK_UNDISTURBED, Pmode); + return gen_int_mode (get_prefer_mask_policy (), Pmode); +} + tree rvv_arg_type_info::get_tree_type (vector_type_index type_idx) const { @@ -546,6 +634,28 @@ function_builder::allocate_argument_types (const function_instance &instance, instance.op_info->args[i].get_tree_type (instance.type.index)); } +/* Apply predication into argument_types. */ +void +function_builder::apply_predication (const function_instance &instance, + tree return_type, + vec &argument_types) const +{ + /* These predication types need to apply merge type. */ + if (instance.pred == PRED_TYPE_tu || instance.pred == PRED_TYPE_tum + || instance.pred == PRED_TYPE_tumu || instance.pred == PRED_TYPE_mu) + argument_types.quick_insert (0, return_type); + + /* These predication types need to apply mask type. */ + tree mask_type = builtin_types[mask_types[instance.type.index]].vector; + if (instance.pred == PRED_TYPE_m || instance.pred == PRED_TYPE_tum + || instance.pred == PRED_TYPE_tumu || instance.pred == PRED_TYPE_mu) + argument_types.quick_insert (0, mask_type); + + /* check if vl parameter need */ + if (instance.base->apply_vl_p ()) + argument_types.quick_push (size_type_node); +} + /* Register all the functions in GROUP. */ void function_builder::register_function_group (const function_group_info &group) @@ -560,6 +670,37 @@ function_builder::append_name (const char *name) obstack_grow (&m_string_obstack, name, strlen (name)); } +/* Add "__riscv_" and "name". */ +void +function_builder::append_base_name (const char *name) +{ + append_name ("__riscv_"); + append_name (name); +} + +/* Add SEW into function name. */ +void +function_builder::append_sew (int sew) +{ + switch (sew) + { + case 8: + append_name ("8"); + break; + case 16: + append_name ("16"); + break; + case 32: + append_name ("32"); + break; + case 64: + append_name ("64"); + break; + default: + gcc_unreachable (); + } +} + /* Zero-terminate and complete the function name being built. */ char * function_builder::finish_name () @@ -694,6 +835,99 @@ function_expander::add_input_operand (unsigned argno) add_input_operand (TYPE_MODE (TREE_TYPE (arg)), x); } +/* Since we may normalize vop/vop_tu/vop_m/vop_tumu.. into a single patter. + We add a undef for the intrinsics that don't need a real merge. */ +void +function_expander::add_vundef_operand (machine_mode mode) +{ + rtx vundef = gen_rtx_UNSPEC (mode, gen_rtvec (1, const0_rtx), UNSPEC_VUNDEF); + add_input_operand (mode, vundef); +} + +/* Add a memory operand with mode MODE and address ADDR. */ +rtx +function_expander::add_mem_operand (machine_mode mode, rtx addr) +{ + gcc_assert (VECTOR_MODE_P (mode)); + rtx mem = gen_rtx_MEM (mode, memory_address (mode, addr)); + /* The memory is only guaranteed to be element-aligned. */ + set_mem_align (mem, GET_MODE_ALIGNMENT (GET_MODE_INNER (mode))); + add_fixed_operand (mem); + return mem; +} + +/* Use contiguous load INSN. */ +rtx +function_expander::use_contiguous_load_insn (insn_code icode) +{ + gcc_assert (call_expr_nargs (exp) > 0); + machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); + tree mask_type = builtin_types[mask_types[type.index]].vector; + machine_mode mask_mode = TYPE_MODE (mask_type); + + /* Record the offset to get the argument. */ + int arg_offset = 0; + + if (use_real_mask_p (pred)) + add_input_operand (arg_offset++); + else + add_all_one_mask_operand (mask_mode); + + if (use_real_merge_p (pred)) + add_input_operand (arg_offset++); + else + add_vundef_operand (mode); + + tree addr_arg = CALL_EXPR_ARG (exp, arg_offset++); + rtx addr = expand_normal (addr_arg); + add_mem_operand (mode, addr); + + for (int argno = arg_offset; argno < call_expr_nargs (exp); argno++) + add_input_operand (argno); + + add_input_operand (Pmode, get_tail_policy_for_pred (pred)); + add_input_operand (Pmode, get_mask_policy_for_pred (pred)); + add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX)); + + return generate_insn (icode); +} + +/* Use contiguous store INSN. */ +rtx +function_expander::use_contiguous_store_insn (insn_code icode) +{ + gcc_assert (call_expr_nargs (exp) > 0); + machine_mode mode = TYPE_MODE (builtin_types[type.index].vector); + tree mask_type = builtin_types[mask_types[type.index]].vector; + machine_mode mask_mode = TYPE_MODE (mask_type); + + /* Record the offset to get the argument. */ + int arg_offset = 0; + + int addr_loc = use_real_mask_p (pred) ? 1 : 0; + tree addr_arg = CALL_EXPR_ARG (exp, addr_loc); + rtx addr = expand_normal (addr_arg); + rtx mem = add_mem_operand (mode, addr); + + if (use_real_mask_p (pred)) + add_input_operand (arg_offset++); + else + add_all_one_mask_operand (mask_mode); + + /* To model "+m" constraint, we include memory operand into input. */ + add_input_operand (mode, mem); + + arg_offset++; + for (int argno = arg_offset; argno < call_expr_nargs (exp); argno++) + add_input_operand (argno); + + add_input_operand (Pmode, get_tail_policy_for_pred (pred)); + add_input_operand (Pmode, get_mask_policy_for_pred (pred)); + add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX)); + + return generate_insn (icode); +} + /* Generate instruction ICODE, given that its operands have already been added to M_OPS. Return the value of the first operand. */ rtx diff --git a/gcc/config/riscv/riscv-vector-builtins.def b/gcc/config/riscv/riscv-vector-builtins.def index b7a633ed376..7636e34d595 100644 --- a/gcc/config/riscv/riscv-vector-builtins.def +++ b/gcc/config/riscv/riscv-vector-builtins.def @@ -44,7 +44,7 @@ along with GCC; see the file COPYING3. If not see #ifndef DEF_RVV_TYPE #define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, SCALAR_TYPE, VECTOR_MODE, \ VECTOR_MODE_MIN_VLEN_32, VECTOR_SUFFIX, SCALAR_SUFFIX, \ - VSETVL_SUFFIX) + VSETVL_SUFFIX, MASK_TYPE) #endif /* Use "DEF_RVV_OP_TYPE" macro to define RVV operand types. @@ -61,212 +61,212 @@ along with GCC; see the file COPYING3. If not see /* SEW/LMUL = 64: Only enable when TARGET_MIN_VLEN > 32 and machine mode = VNx1BImode. */ -DEF_RVV_TYPE (vbool64_t, 14, __rvv_bool64_t, boolean, VNx1BI, VOID, _b64, , ) +DEF_RVV_TYPE (vbool64_t, 14, __rvv_bool64_t, boolean, VNx1BI, VOID, _b64, , , vbool64_t) /* SEW/LMUL = 32: Machine mode = VNx2BImode when TARGET_MIN_VLEN > 32. Machine mode = VNx1BImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vbool32_t, 14, __rvv_bool32_t, boolean, VNx2BI, VNx1BI, _b32, , ) +DEF_RVV_TYPE (vbool32_t, 14, __rvv_bool32_t, boolean, VNx2BI, VNx1BI, _b32, , , vbool32_t) /* SEW/LMUL = 16: Machine mode = VNx2BImode when TARGET_MIN_VLEN = 32. Machine mode = VNx4BImode when TARGET_MIN_VLEN > 32. */ -DEF_RVV_TYPE (vbool16_t, 14, __rvv_bool16_t, boolean, VNx4BI, VNx2BI, _b16, , ) +DEF_RVV_TYPE (vbool16_t, 14, __rvv_bool16_t, boolean, VNx4BI, VNx2BI, _b16, , , vbool16_t) /* SEW/LMUL = 8: Machine mode = VNx8BImode when TARGET_MIN_VLEN > 32. Machine mode = VNx4BImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vbool8_t, 13, __rvv_bool8_t, boolean, VNx8BI, VNx4BI, _b8, , ) +DEF_RVV_TYPE (vbool8_t, 13, __rvv_bool8_t, boolean, VNx8BI, VNx4BI, _b8, , , vbool8_t) /* SEW/LMUL = 4: Machine mode = VNx16BImode when TARGET_MIN_VLEN > 32. Machine mode = VNx8BImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vbool4_t, 13, __rvv_bool4_t, boolean, VNx16BI, VNx8BI, _b4, , ) +DEF_RVV_TYPE (vbool4_t, 13, __rvv_bool4_t, boolean, VNx16BI, VNx8BI, _b4, , , vbool4_t) /* SEW/LMUL = 2: Machine mode = VNx32BImode when TARGET_MIN_VLEN > 32. Machine mode = VNx16BImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vbool2_t, 13, __rvv_bool2_t, boolean, VNx32BI, VNx16BI, _b2, , ) +DEF_RVV_TYPE (vbool2_t, 13, __rvv_bool2_t, boolean, VNx32BI, VNx16BI, _b2, , , vbool2_t) /* SEW/LMUL = 1: Machine mode = VNx64BImode when TARGET_MIN_VLEN > 32. Machine mode = VNx32BImode when TARGET_MIN_VLEN = 32. */ -DEF_RVV_TYPE (vbool1_t, 13, __rvv_bool1_t, boolean, VNx64BI, VNx32BI, _b1, , ) +DEF_RVV_TYPE (vbool1_t, 13, __rvv_bool1_t, boolean, VNx64BI, VNx32BI, _b1, , , vbool1_t) /* LMUL = 1/8: Only enble when TARGET_MIN_VLEN > 32 and machine mode = VNx1QImode. */ DEF_RVV_TYPE (vint8mf8_t, 15, __rvv_int8mf8_t, intQI, VNx1QI, VOID, _i8mf8, _i8, - _e8mf8) + _e8mf8, vbool64_t) DEF_RVV_TYPE (vuint8mf8_t, 16, __rvv_uint8mf8_t, unsigned_intQI, VNx1QI, VOID, - _u8mf8, _u8, _e8mf8) + _u8mf8, _u8, _e8mf8, vbool64_t) /* LMUL = 1/4: Machine mode = VNx2QImode when TARGET_MIN_VLEN > 32. Machine mode = VNx1QImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint8mf4_t, 15, __rvv_int8mf4_t, intQI, VNx2QI, VNx1QI, _i8mf4, - _i8, _e8mf4) + _i8, _e8mf4, vbool32_t) DEF_RVV_TYPE (vuint8mf4_t, 16, __rvv_uint8mf4_t, unsigned_intQI, VNx2QI, VNx1QI, - _u8mf4, _u8, _e8mf4) + _u8mf4, _u8, _e8mf4, vbool32_t) /* LMUL = 1/2: Machine mode = VNx4QImode when TARGET_MIN_VLEN > 32. Machine mode = VNx2QImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint8mf2_t, 15, __rvv_int8mf2_t, intQI, VNx4QI, VNx2QI, _i8mf2, - _i8, _e8mf2) + _i8, _e8mf2, vbool16_t) DEF_RVV_TYPE (vuint8mf2_t, 16, __rvv_uint8mf2_t, unsigned_intQI, VNx4QI, VNx2QI, - _u8mf2, _u8, _e8mf2) + _u8mf2, _u8, _e8mf2, vbool16_t) /* LMUL = 1: Machine mode = VNx8QImode when TARGET_MIN_VLEN > 32. Machine mode = VNx4QImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint8m1_t, 14, __rvv_int8m1_t, intQI, VNx8QI, VNx4QI, _i8m1, _i8, - _e8m1) + _e8m1, vbool8_t) DEF_RVV_TYPE (vuint8m1_t, 15, __rvv_uint8m1_t, unsigned_intQI, VNx8QI, VNx4QI, - _u8m1, _u8, _e8m1) + _u8m1, _u8, _e8m1, vbool8_t) /* LMUL = 2: Machine mode = VNx16QImode when TARGET_MIN_VLEN > 32. Machine mode = VNx8QImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint8m2_t, 14, __rvv_int8m2_t, intQI, VNx16QI, VNx8QI, _i8m2, _i8, - _e8m2) + _e8m2, vbool4_t) DEF_RVV_TYPE (vuint8m2_t, 15, __rvv_uint8m2_t, unsigned_intQI, VNx16QI, VNx8QI, - _u8m2, _u8, _e8m2) + _u8m2, _u8, _e8m2, vbool4_t) /* LMUL = 4: Machine mode = VNx32QImode when TARGET_MIN_VLEN > 32. Machine mode = VNx16QImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint8m4_t, 14, __rvv_int8m4_t, intQI, VNx32QI, VNx16QI, _i8m4, - _i8, _e8m4) + _i8, _e8m4, vbool2_t) DEF_RVV_TYPE (vuint8m4_t, 15, __rvv_uint8m4_t, unsigned_intQI, VNx32QI, VNx16QI, - _u8m4, _u8, _e8m4) + _u8m4, _u8, _e8m4, vbool2_t) /* LMUL = 8: Machine mode = VNx64QImode when TARGET_MIN_VLEN > 32. Machine mode = VNx32QImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint8m8_t, 14, __rvv_int8m8_t, intQI, VNx64QI, VNx32QI, _i8m8, - _i8, _e8m8) + _i8, _e8m8, vbool1_t) DEF_RVV_TYPE (vuint8m8_t, 15, __rvv_uint8m8_t, unsigned_intQI, VNx64QI, VNx32QI, - _u8m8, _u8, _e8m8) + _u8m8, _u8, _e8m8, vbool1_t) /* LMUL = 1/4: Only enble when TARGET_MIN_VLEN > 32 and machine mode = VNx1HImode. */ DEF_RVV_TYPE (vint16mf4_t, 16, __rvv_int16mf4_t, intHI, VNx1HI, VOID, _i16mf4, - _i16, _e16mf4) + _i16, _e16mf4, vbool64_t) DEF_RVV_TYPE (vuint16mf4_t, 17, __rvv_uint16mf4_t, unsigned_intHI, VNx1HI, VOID, - _u16mf4, _u16, _e16mf4) + _u16mf4, _u16, _e16mf4, vbool64_t) /* LMUL = 1/2: Machine mode = VNx2HImode when TARGET_MIN_VLEN > 32. Machine mode = VNx1HImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint16mf2_t, 16, __rvv_int16mf2_t, intHI, VNx2HI, VNx1HI, _i16mf2, - _i16, _e16mf2) + _i16, _e16mf2, vbool32_t) DEF_RVV_TYPE (vuint16mf2_t, 17, __rvv_uint16mf2_t, unsigned_intHI, VNx2HI, - VNx1HI, _u16mf2, _u16, _e16mf2) + VNx1HI, _u16mf2, _u16, _e16mf2, vbool32_t) /* LMUL = 1: Machine mode = VNx4HImode when TARGET_MIN_VLEN > 32. Machine mode = VNx2HImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint16m1_t, 15, __rvv_int16m1_t, intHI, VNx4HI, VNx2HI, _i16m1, - _i16, _e16m1) + _i16, _e16m1, vbool16_t) DEF_RVV_TYPE (vuint16m1_t, 16, __rvv_uint16m1_t, unsigned_intHI, VNx4HI, VNx2HI, - _u16m1, _u16, _e16m1) + _u16m1, _u16, _e16m1, vbool16_t) /* LMUL = 2: Machine mode = VNx8HImode when TARGET_MIN_VLEN > 32. Machine mode = VNx4HImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint16m2_t, 15, __rvv_int16m2_t, intHI, VNx8HI, VNx4HI, _i16m2, - _i16, _e16m2) + _i16, _e16m2, vbool8_t) DEF_RVV_TYPE (vuint16m2_t, 16, __rvv_uint16m2_t, unsigned_intHI, VNx8HI, VNx4HI, - _u16m2, _u16, _e16m2) + _u16m2, _u16, _e16m2, vbool8_t) /* LMUL = 4: Machine mode = VNx16HImode when TARGET_MIN_VLEN > 32. Machine mode = VNx8HImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint16m4_t, 15, __rvv_int16m4_t, intHI, VNx16HI, VNx8HI, _i16m4, - _i16, _e16m4) + _i16, _e16m4, vbool4_t) DEF_RVV_TYPE (vuint16m4_t, 16, __rvv_uint16m4_t, unsigned_intHI, VNx16HI, - VNx8HI, _u16m4, _u16, _e16m4) + VNx8HI, _u16m4, _u16, _e16m4, vbool4_t) /* LMUL = 8: Machine mode = VNx32HImode when TARGET_MIN_VLEN > 32. Machine mode = VNx16HImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint16m8_t, 15, __rvv_int16m8_t, intHI, VNx32HI, VNx16HI, _i16m8, - _i16, _e16m8) + _i16, _e16m8, vbool2_t) DEF_RVV_TYPE (vuint16m8_t, 16, __rvv_uint16m8_t, unsigned_intHI, VNx32HI, - VNx16HI, _u16m8, _u16, _e16m8) + VNx16HI, _u16m8, _u16, _e16m8, vbool2_t) /* LMUL = 1/2: Only enble when TARGET_MIN_VLEN > 32 and machine mode = VNx1SImode. */ DEF_RVV_TYPE (vint32mf2_t, 16, __rvv_int32mf2_t, int32, VNx1SI, VOID, _i32mf2, - _i32, _e32mf2) + _i32, _e32mf2, vbool64_t) DEF_RVV_TYPE (vuint32mf2_t, 17, __rvv_uint32mf2_t, unsigned_int32, VNx1SI, VOID, - _u32mf2, _u32, _e32mf2) + _u32mf2, _u32, _e32mf2, vbool64_t) /* LMUL = 1: Machine mode = VNx2SImode when TARGET_MIN_VLEN > 32. Machine mode = VNx1SImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint32m1_t, 15, __rvv_int32m1_t, int32, VNx2SI, VNx1SI, _i32m1, - _i32, _e32m1) + _i32, _e32m1, vbool32_t) DEF_RVV_TYPE (vuint32m1_t, 16, __rvv_uint32m1_t, unsigned_int32, VNx2SI, VNx1SI, - _u32m1, _u32, _e32m1) + _u32m1, _u32, _e32m1, vbool32_t) /* LMUL = 2: Machine mode = VNx4SImode when TARGET_MIN_VLEN > 32. Machine mode = VNx2SImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint32m2_t, 15, __rvv_int32m2_t, int32, VNx4SI, VNx2SI, _i32m2, - _i32, _e32m2) + _i32, _e32m2, vbool16_t) DEF_RVV_TYPE (vuint32m2_t, 16, __rvv_uint32m2_t, unsigned_int32, VNx4SI, VNx2SI, - _u32m2, _u32, _e32m2) + _u32m2, _u32, _e32m2, vbool16_t) /* LMUL = 4: Machine mode = VNx8SImode when TARGET_MIN_VLEN > 32. Machine mode = VNx4SImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint32m4_t, 15, __rvv_int32m4_t, int32, VNx8SI, VNx4SI, _i32m4, - _i32, _e32m4) + _i32, _e32m4, vbool8_t) DEF_RVV_TYPE (vuint32m4_t, 16, __rvv_uint32m4_t, unsigned_int32, VNx8SI, VNx4SI, - _u32m4, _u32, _e32m4) + _u32m4, _u32, _e32m4, vbool8_t) /* LMUL = 8: Machine mode = VNx16SImode when TARGET_MIN_VLEN > 32. Machine mode = VNx8SImode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vint32m8_t, 15, __rvv_int32m8_t, int32, VNx16SI, VNx8SI, _i32m8, - _i32, _e32m8) + _i32, _e32m8, vbool4_t) DEF_RVV_TYPE (vuint32m8_t, 16, __rvv_uint32m8_t, unsigned_int32, VNx16SI, - VNx8SI, _u32m8, _u32, _e32m8) + VNx8SI, _u32m8, _u32, _e32m8, vbool4_t) /* SEW = 64: Disable when TARGET_MIN_VLEN > 32. */ DEF_RVV_TYPE (vint64m1_t, 15, __rvv_int64m1_t, intDI, VNx1DI, VOID, _i64m1, - _i64, _e64m1) + _i64, _e64m1, vbool64_t) DEF_RVV_TYPE (vuint64m1_t, 16, __rvv_uint64m1_t, unsigned_intDI, VNx1DI, VOID, - _u64m1, _u64, _e64m1) + _u64m1, _u64, _e64m1, vbool64_t) DEF_RVV_TYPE (vint64m2_t, 15, __rvv_int64m2_t, intDI, VNx2DI, VOID, _i64m2, - _i64, _e64m2) + _i64, _e64m2, vbool32_t) DEF_RVV_TYPE (vuint64m2_t, 16, __rvv_uint64m2_t, unsigned_intDI, VNx2DI, VOID, - _u64m2, _u64, _e64m2) + _u64m2, _u64, _e64m2, vbool32_t) DEF_RVV_TYPE (vint64m4_t, 15, __rvv_int64m4_t, intDI, VNx4DI, VOID, _i64m4, - _i64, _e64m4) + _i64, _e64m4, vbool16_t) DEF_RVV_TYPE (vuint64m4_t, 16, __rvv_uint64m4_t, unsigned_intDI, VNx4DI, VOID, - _u64m4, _u64, _e64m4) + _u64m4, _u64, _e64m4, vbool16_t) DEF_RVV_TYPE (vint64m8_t, 15, __rvv_int64m8_t, intDI, VNx8DI, VOID, _i64m8, - _i64, _e64m8) + _i64, _e64m8, vbool8_t) DEF_RVV_TYPE (vuint64m8_t, 16, __rvv_uint64m8_t, unsigned_intDI, VNx8DI, VOID, - _u64m8, _u64, _e64m8) + _u64m8, _u64, _e64m8, vbool8_t) /* LMUL = 1/2: Only enble when TARGET_MIN_VLEN > 32 and machine mode = VNx1SFmode. */ DEF_RVV_TYPE (vfloat32mf2_t, 18, __rvv_float32mf2_t, float, VNx1SF, VOID, - _f32mf2, _f32, _e32mf2) + _f32mf2, _f32, _e32mf2, vbool64_t) /* LMUL = 1: Machine mode = VNx2SFmode when TARGET_MIN_VLEN > 32. Machine mode = VNx1SFmode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vfloat32m1_t, 17, __rvv_float32m1_t, float, VNx2SF, VNx1SF, - _f32m1, _f32, _e32m1) + _f32m1, _f32, _e32m1, vbool32_t) /* LMUL = 2: Machine mode = VNx4SFmode when TARGET_MIN_VLEN > 32. Machine mode = VNx2SFmode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vfloat32m2_t, 17, __rvv_float32m2_t, float, VNx4SF, VNx2SF, - _f32m2, _f32, _e32m2) + _f32m2, _f32, _e32m2, vbool16_t) /* LMUL = 4: Machine mode = VNx8SFmode when TARGET_MIN_VLEN > 32. Machine mode = VNx4SFmode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vfloat32m4_t, 17, __rvv_float32m4_t, float, VNx8SF, VNx4SF, - _f32m4, _f32, _e32m4) + _f32m4, _f32, _e32m4, vbool8_t) /* LMUL = 8: Machine mode = VNx16SFmode when TARGET_MIN_VLEN > 32. Machine mode = VNx8SFmode when TARGET_MIN_VLEN = 32. */ DEF_RVV_TYPE (vfloat32m8_t, 17, __rvv_float32m8_t, float, VNx16SF, VNx8SF, - _f32m8, _f32, _e32m8) + _f32m8, _f32, _e32m8, vbool4_t) /* SEW = 64: Disable when TARGET_VECTOR_FP64. */ DEF_RVV_TYPE (vfloat64m1_t, 17, __rvv_float64m1_t, double, VNx1DF, VOID, _f64m1, - _f64, _e64m1) + _f64, _e64m1, vbool64_t) DEF_RVV_TYPE (vfloat64m2_t, 17, __rvv_float64m2_t, double, VNx2DF, VOID, _f64m2, - _f64, _e64m2) + _f64, _e64m2, vbool32_t) DEF_RVV_TYPE (vfloat64m4_t, 17, __rvv_float64m4_t, double, VNx4DF, VOID, _f64m4, - _f64, _e64m4) + _f64, _e64m4, vbool16_t) DEF_RVV_TYPE (vfloat64m8_t, 17, __rvv_float64m8_t, double, VNx8DF, VOID, _f64m8, - _f64, _e64m8) + _f64, _e64m8, vbool8_t) DEF_RVV_OP_TYPE (vv) DEF_RVV_OP_TYPE (vx) diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h index 425da12326c..c13df99cb5b 100644 --- a/gcc/config/riscv/riscv-vector-builtins.h +++ b/gcc/config/riscv/riscv-vector-builtins.h @@ -264,10 +264,13 @@ public: ~function_builder (); void allocate_argument_types (const function_instance &, vec &) const; + void apply_predication (const function_instance &, tree, vec &) const; void add_unique_function (const function_instance &, const function_shape *, tree, vec &); void register_function_group (const function_group_info &); void append_name (const char *); + void append_base_name (const char *); + void append_sew (int); char *finish_name (); private: @@ -315,6 +318,16 @@ public: void add_input_operand (machine_mode, rtx); void add_input_operand (unsigned argno); + void add_output_operand (machine_mode, rtx); + void add_all_one_mask_operand (machine_mode mode); + void add_vundef_operand (machine_mode mode); + void add_fixed_operand (rtx); + rtx add_mem_operand (machine_mode, rtx); + + machine_mode vector_mode (void) const; + + rtx use_contiguous_load_insn (insn_code); + rtx use_contiguous_store_insn (insn_code); rtx generate_insn (insn_code); /* The function call expression. */ @@ -342,6 +355,12 @@ public: in addition to reading its arguments and returning a result. */ virtual unsigned int call_properties (const function_instance &) const; + /* Return true if intrinsics should apply vl operand. */ + virtual bool apply_vl_p () const; + + /* Return true if intrinsic can be overloaded. */ + virtual bool can_be_overloaded_p (enum predication_type_index) const; + /* Expand the given call into rtl. Return the result of the function, or an arbitrary value if the function doesn't return a result. */ virtual rtx expand (function_expander &) const = 0; @@ -394,6 +413,37 @@ function_expander::add_input_operand (machine_mode mode, rtx op) create_input_operand (&m_ops[opno++], op, mode); } +/* Create output and add it into M_OPS and increase OPNO. */ +inline void +function_expander::add_output_operand (machine_mode mode, rtx target) +{ + create_output_operand (&m_ops[opno++], target, mode); +} + +/* Since we may normalize vop/vop_tu/vop_m/vop_tumu.. into a single patter. + We add a fake all true mask for the intrinsics that don't need a real mask. + */ +inline void +function_expander::add_all_one_mask_operand (machine_mode mode) +{ + add_input_operand (mode, CONSTM1_RTX (mode)); +} + +/* Add an operand that must be X. The only way of legitimizing an + invalid X is to reload the address of a MEM. */ +inline void +function_expander::add_fixed_operand (rtx x) +{ + create_fixed_operand (&m_ops[opno++], x); +} + +/* Return the machine_mode of the corresponding vector type. */ +inline machine_mode +function_expander::vector_mode (void) const +{ + return TYPE_MODE (builtin_types[type.index].vector); +} + /* Default implementation of function_base::call_properties, with conservatively correct behavior for floating-point instructions. */ inline unsigned int @@ -405,6 +455,21 @@ function_base::call_properties (const function_instance &instance) const return flags; } +/* We choose to apply vl operand by default since most of the intrinsics + has vl operand. */ +inline bool +function_base::apply_vl_p () const +{ + return true; +} + +/* Since most of intrinsics can be overloaded, we set it true by default. */ +inline bool +function_base::can_be_overloaded_p (enum predication_type_index) const +{ + return true; +} + } // end namespace riscv_vector #endif diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index 72f1e4059ab..01530c1ae75 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -302,10 +302,6 @@ get_vl (rtx_insn *rinsn) { if (has_vl_op (rinsn)) { - /* We only call get_vl for VLMAX use VTYPE instruction. - It's used to get the VL operand to emit VLMAX VSETVL instruction: - vsetvl a5,zero,e32,m1,ta,ma. */ - gcc_assert (get_attr_avl_type (rinsn) == VLMAX); extract_insn_cached (rinsn); return recog_data.operand[get_attr_vl_op_idx (rinsn)]; } diff --git a/gcc/config/riscv/t-riscv b/gcc/config/riscv/t-riscv index 7af9f5402ec..d30e0235356 100644 --- a/gcc/config/riscv/t-riscv +++ b/gcc/config/riscv/t-riscv @@ -9,7 +9,7 @@ riscv-vector-builtins.o: $(srcdir)/config/riscv/riscv-vector-builtins.cc \ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) $(TM_P_H) \ memmodel.h insn-codes.h $(OPTABS_H) $(RECOG_H) $(DIAGNOSTIC_H) $(EXPR_H) \ $(FUNCTION_H) fold-const.h gimplify.h explow.h stor-layout.h $(REGS_H) \ - alias.h langhooks.h attribs.h stringpool.h \ + alias.h langhooks.h attribs.h stringpool.h emit-rtl.h \ $(srcdir)/config/riscv/riscv-vector-builtins.h \ $(srcdir)/config/riscv/riscv-vector-builtins-shapes.h \ $(srcdir)/config/riscv/riscv-vector-builtins-bases.h \