From patchwork Thu May 11 10:26:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Dapp X-Patchwork-Id: 92473 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp4259238vqo; Thu, 11 May 2023 03:27:45 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7csQlvA6zHZicfae2bizYBvWDkL7cSWI+H+xjeFUUWaDDnwXYaC9IJNEiNkE+X1q+XdRD/ X-Received: by 2002:a17:907:8a27:b0:959:266b:dea8 with SMTP id sc39-20020a1709078a2700b00959266bdea8mr16694417ejc.2.1683800865700; Thu, 11 May 2023 03:27:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1683800865; cv=none; d=google.com; s=arc-20160816; b=TBAFCN9OvkeulIZzTLKXzja2f1Q7BbzpTF/GTWB9UwftEN2NArdrhd45ryRPmHHQci tj9Q+NIpOuZu6a9JHGIGUc9GQeDbFIeqrUffaWdly6bDmnmvPKEXfglf5OxdrLI3oyag CCgyX8xtIb+B5rTyvy4w3SPDpNdWGG6nSlDsnHVx76OD7XtgJ1Vq65LQA9LS6dske3T5 Lc7J6nDyyA1O+lggMR3h41UtOXrCtmppUxE679Y2h/6aSeyKRvUfbAZLmraawVZeOpc3 b2mag4FzqWHvmM60yd+zuKE2Q0f7JVvHvQ9TlPGgOHCxXNTaXm7HJKrf4k3EEjbzHMsi AuFQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:in-reply-to:cc:references:to :content-language:subject:user-agent:mime-version:date:message-id :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=XmfZNzjM0Pc0wuQ3p2N+HgVbeGEvhMMW9nGaNb9PPT8=; b=jXzTOA8h4MYd4x8wvAXJ/g2KHZhCMhHmNBqYMYGzl+JDfFvLr9bGAcR7eoSkBVmV9I Lr85sjNEMGURZAB3UcAS7FpEuOgMoDnpKl3JK0MBRQjXGzdDjSpwR7Gp1JHRl4+Pn8ar xrSSh6CkBP2/koQYzeOQKJYOoKLTUGzbxKbu4hMPgMPtBRsQIgS52uKNxJPMs17aWj0K ybTAbKhDDmnWARo2Xpl7mJEeNI3bqDpun5sJKNmuUI6k3ltQ3W1LgP1cIA8EsmyCfDP8 L2pXkhXvUkrmRoBy6Q65zawJnYmREQv95alc1k6vNBrQdOVE2Fnb1MW3yCpf4vzFC1xK xj/g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=auyaOGjs; 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"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id n8-20020a1709067b4800b0095854842b3fsi2152364ejo.614.2023.05.11.03.27.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 May 2023 03:27:45 -0700 (PDT) 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; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=auyaOGjs; 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"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3DF503857006 for ; Thu, 11 May 2023 10:27:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3DF503857006 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1683800864; bh=XmfZNzjM0Pc0wuQ3p2N+HgVbeGEvhMMW9nGaNb9PPT8=; h=Date:Subject:To:References:Cc:In-Reply-To:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=auyaOGjs5XBY1WK8QoKTwBEXl/O85mvdG5nBH3m0fH0eObFss931gamgHYsHaPARx u8l2RM6sdxAh3GVxkezInNKHkXX6nUJzoBiUE9vHjHiFugyLKZgh3Fs8kjDEgJfnLH i6+Av5x1I7JjSRyhHskIQByoiGmbF5Mp8ZLI56I4= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) by sourceware.org (Postfix) with ESMTPS id 04EC83858D33 for ; Thu, 11 May 2023 10:26:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 04EC83858D33 Received: by mail-ed1-x52a.google.com with SMTP id 4fb4d7f45d1cf-50bc4b88998so14871550a12.3 for ; Thu, 11 May 2023 03:26:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683800817; x=1686392817; h=content-transfer-encoding:in-reply-to:cc:from:references:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=XmfZNzjM0Pc0wuQ3p2N+HgVbeGEvhMMW9nGaNb9PPT8=; b=Z+YeJqkExxqNYBvQ11B6BaKlRQcIx91yG37Hn4989bdJ8EJNS/m/7jI+rrLI3tUCvd 3Ko1wC9yqpSHGeXL8G9FFgtbnYxNQoFGTF9JGb+FYMjyPKN+ENBC9AJt3uHWIs4pJRzN 6WW+/gqDYXNnpLZs4Q1045oGypKlgh+O+Hta96lripLnhm7AFPogvHb+spq88FtIGztH zagyVYsv2CYYYULyx/ygEJNEMAsUb2yfepq5/nACzQ3pmjKMIU2g3lM75vVEVJDnE34Q ccjW+9rtjUGqq2VyviPYVdxMCQhOlMY4Mp71uqIBBW7bqLWkAFKP4jHHKYMqDLSpSMfS 9I7Q== X-Gm-Message-State: AC+VfDx0DJdUHc50L9QFJDDoeZg16Sqn1ZslAtCVDD+sWy+iusOg4Pu7 2o+q/ctH/RtwgXEpL8AwkJA= X-Received: by 2002:a05:6402:549:b0:50b:f70b:9928 with SMTP id i9-20020a056402054900b0050bf70b9928mr17630305edx.18.1683800817446; Thu, 11 May 2023 03:26:57 -0700 (PDT) Received: from [192.168.1.23] (ip-046-005-130-086.um12.pools.vodafone-ip.de. [46.5.130.86]) by smtp.gmail.com with ESMTPSA id o22-20020aa7d3d6000000b0050696c2d2f6sm2666145edr.88.2023.05.11.03.26.56 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 11 May 2023 03:26:56 -0700 (PDT) Message-ID: Date: Thu, 11 May 2023 12:26:55 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.10.0 Subject: [PATCH v2] RISC-V: Add vectorized binops and insn_expander helpers. Content-Language: en-US To: =?utf-8?b?6ZKf5bGF5ZOy?= , gcc-patches , "kito.cheng" , Michael Collison , palmer , Jeff Law References: <0886290d-0b1f-7aee-23b0-43c3dac852b5@gmail.com> <70DCB409927A1FCB+202305102343023760963@rivai.ai> <2d59325a-4394-55a9-9672-df08b8089771@gmail.com> <26EA7AD78CFB10DB+2023051106550856361413@rivai.ai> Cc: rdapp.gcc@gmail.com In-Reply-To: <26EA7AD78CFB10DB+2023051106550856361413@rivai.ai> X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_ASCII_DIVIDERS, KAM_MANYTO, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , X-Patchwork-Original-From: Robin Dapp via Gcc-patches From: Robin Dapp Reply-To: Robin Dapp 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?1765593176140381559?= X-GMAIL-MSGID: =?utf-8?q?1765593176140381559?= Changes from v1: - Rebase against Juzhe's vec_series patch. - Get rid of redundant scalar mode setting. This patch adds basic binary integer operations support. It is based on Michael Collison's work and makes use of the existing helpers in riscv-c.cc. It introduces emit_nonvlmax_binop which, in turn, uses emit_pred_binop. Setting the destination as well as the mask and the length are factored out into separate functions. gcc/ChangeLog: * config/riscv/autovec.md (3): Add integer binops. * config/riscv/riscv-protos.h (emit_nonvlmax_binop): Declare. * config/riscv/riscv-v.cc (emit_pred_op): New function. (set_expander_dest_and_mask): New function. (emit_pred_binop): New function. (emit_nonvlmax_binop): New function. Co-authored-by: Michael Collison --- gcc/config/riscv/autovec.md | 37 ++++++++ gcc/config/riscv/riscv-protos.h | 2 + gcc/config/riscv/riscv-v.cc | 148 ++++++++++++++++++-------------- 3 files changed, 123 insertions(+), 64 deletions(-) diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 99dc4f046b0..e249f4be704 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -82,3 +82,40 @@ (define_expand "@vec_series" DONE; } ) + +;; ======================================================================== +;; == Vector operations +;; ========================================================================= + +;; ------------------------------------------------------------------------- +;; ---- [INT] Binary operations +;; ------------------------------------------------------------------------- +;; Includes: +;; - vadd.vv/vsub.vv/... +;; - vadd.vi/vsub.vi/... +;; ------------------------------------------------------------------------- + +(define_expand "3" + [(set (match_operand:VI 0 "register_operand") + (any_int_binop:VI + (match_operand:VI 1 "") + (match_operand:VI 2 "")))] + "TARGET_VECTOR" +{ + if (!register_operand (operands[2], mode)) + { + rtx cst; + gcc_assert (const_vec_duplicate_p(operands[2], &cst)); + riscv_vector::emit_nonvlmax_binop (code_for_pred_scalar + (, mode), + operands[0], operands[1], cst, + NULL, mode, + mode); + } + else + riscv_vector::emit_nonvlmax_binop (code_for_pred + (, mode), + operands[0], operands[1], operands[2], + NULL, mode); + DONE; +}) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index e8a728ae226..4d0589e502c 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -169,6 +169,8 @@ void emit_hard_vlmax_vsetvl (machine_mode, rtx); void emit_vlmax_op (unsigned, rtx, rtx, machine_mode); void emit_vlmax_op (unsigned, rtx, rtx, rtx, machine_mode); void emit_nonvlmax_op (unsigned, rtx, rtx, rtx, machine_mode); +void emit_nonvlmax_binop (unsigned, rtx, rtx, rtx, rtx, machine_mode, + machine_mode = VOIDmode); enum vlmul_type get_vlmul (machine_mode); unsigned int get_ratio (machine_mode); unsigned int get_nf (machine_mode); diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 381e6601a17..8f46226d571 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -53,7 +53,7 @@ namespace riscv_vector { template class insn_expander { public: - insn_expander () : m_opno (0) {} + insn_expander () : m_opno (0), has_dest(false) {} void add_output_operand (rtx x, machine_mode mode) { create_output_operand (&m_ops[m_opno++], x, mode); @@ -84,6 +84,44 @@ public: add_input_operand (gen_int_mode (type, Pmode), Pmode); } + void set_dest_and_mask (rtx mask, rtx dest, machine_mode mask_mode) + { + dest_mode = GET_MODE (dest); + has_dest = true; + + add_output_operand (dest, dest_mode); + + if (mask) + add_input_operand (mask, GET_MODE (mask)); + else + add_all_one_mask_operand (mask_mode); + + add_vundef_operand (dest_mode); + } + + void set_len_and_policy (rtx len, bool vlmax_p) + { + gcc_assert (has_dest); + gcc_assert (len || vlmax_p); + + if (len) + add_input_operand (len, Pmode); + else + { + rtx vlmax = gen_reg_rtx (Pmode); + emit_vlmax_vsetvl (dest_mode, vlmax); + add_input_operand (vlmax, Pmode); + } + + if (GET_MODE_CLASS (dest_mode) != MODE_VECTOR_BOOL) + add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ()); + + if (vlmax_p) + add_avl_type_operand (avl_type::VLMAX); + else + add_avl_type_operand (avl_type::NONVLMAX); + } + void expand (enum insn_code icode, bool temporary_volatile_p = false) { if (temporary_volatile_p) @@ -97,6 +135,8 @@ public: private: int m_opno; + bool has_dest; + machine_mode dest_mode; expand_operand m_ops[MAX_OPERANDS]; }; @@ -195,37 +235,41 @@ emit_pred_op (unsigned icode, rtx mask, rtx dest, rtx src, rtx len, machine_mode mask_mode, bool vlmax_p) { insn_expander<8> e; - machine_mode mode = GET_MODE (dest); + e.set_dest_and_mask (mask, dest, mask_mode); - e.add_output_operand (dest, mode); + e.add_input_operand (src, GET_MODE (src)); - if (mask) - e.add_input_operand (mask, GET_MODE (mask)); - else - e.add_all_one_mask_operand (mask_mode); + e.set_len_and_policy (len, vlmax_p); - e.add_vundef_operand (mode); + e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src)); +} - e.add_input_operand (src, GET_MODE (src)); +/* Emit an RVV binop. If one of SRC1 and SRC2 is a scalar operand, its mode is + specified using SCALAR_MODE. */ +static void +emit_pred_binop (unsigned icode, rtx mask, rtx dest, rtx src1, rtx src2, + rtx len, machine_mode mask_mode, machine_mode scalar_mode, + bool vlmax_p) +{ + insn_expander<9> e; + e.set_dest_and_mask (mask, dest, mask_mode); - if (len) - e.add_input_operand (len, Pmode); - else - { - rtx vlmax = gen_reg_rtx (Pmode); - emit_vlmax_vsetvl (mode, vlmax); - e.add_input_operand (vlmax, Pmode); - } + gcc_assert (VECTOR_MODE_P (GET_MODE (src1)) + || VECTOR_MODE_P (GET_MODE (src2))); - if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL) - e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ()); + if (VECTOR_MODE_P (GET_MODE (src1))) + e.add_input_operand (src1, GET_MODE (src1)); + else + e.add_input_operand (src1, scalar_mode); - if (vlmax_p) - e.add_avl_type_operand (avl_type::VLMAX); + if (VECTOR_MODE_P (GET_MODE (src2))) + e.add_input_operand (src2, GET_MODE (src2)); else - e.add_avl_type_operand (avl_type::NONVLMAX); + e.add_input_operand (src2, scalar_mode); - e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src)); + e.set_len_and_policy (len, vlmax_p); + + e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src1) || MEM_P (src2)); } void @@ -248,49 +292,25 @@ emit_nonvlmax_op (unsigned icode, rtx dest, rtx src, rtx len, emit_pred_op (icode, NULL_RTX, dest, src, len, mask_mode, false); } -/* Emit binary operations. */ - -static void -emit_binop (unsigned icode, rtx *ops, machine_mode mask_mode, - machine_mode scalar_mode) +void +emit_nonvlmax_binop (unsigned icode, rtx dest, rtx src1, rtx src2, rtx len, + machine_mode mask_mode, machine_mode scalar_mode) { - insn_expander<9> e; - machine_mode mode = GET_MODE (ops[0]); - e.add_output_operand (ops[0], mode); - e.add_all_one_mask_operand (mask_mode); - e.add_vundef_operand (mode); - if (VECTOR_MODE_P (GET_MODE (ops[1]))) - e.add_input_operand (ops[1], GET_MODE (ops[1])); - else - e.add_input_operand (ops[1], scalar_mode); - if (VECTOR_MODE_P (GET_MODE (ops[2]))) - e.add_input_operand (ops[2], GET_MODE (ops[2])); - else - e.add_input_operand (ops[2], scalar_mode); - rtx vlmax = gen_reg_rtx (Pmode); - emit_vlmax_vsetvl (mode, vlmax); - e.add_input_operand (vlmax, Pmode); - e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ()); - e.add_avl_type_operand (avl_type::VLMAX); - e.expand ((enum insn_code) icode, false); + emit_pred_binop (icode, NULL_RTX, dest, src1, src2, len, mask_mode, + scalar_mode, len ? false : true); } /* Emit vid.v instruction. */ static void -emit_index_op (rtx target, machine_mode mask_mode) +emit_index_op (rtx dest, machine_mode mask_mode) { insn_expander<7> e; - machine_mode mode = GET_MODE (target); - e.add_output_operand (target, mode); - e.add_all_one_mask_operand (mask_mode); - e.add_vundef_operand (mode); - rtx vlmax = gen_reg_rtx (Pmode); - emit_vlmax_vsetvl (mode, vlmax); - e.add_input_operand (vlmax, Pmode); - e.add_policy_operand (get_prefer_tail_policy (), get_prefer_mask_policy ()); - e.add_avl_type_operand (avl_type::VLMAX); - e.expand (code_for_pred_series (mode), false); + e.set_dest_and_mask (NULL, dest, mask_mode); + + e.set_len_and_policy (NULL, true); + + e.expand (code_for_pred_series (GET_MODE (dest)), false); } /* Expand series const vector. */ @@ -324,15 +344,15 @@ expand_vec_series (rtx dest, rtx base, rtx step) /* Emit logical left shift operation. */ int shift = exact_log2 (INTVAL (step)); rtx shift_amount = gen_int_mode (shift, Pmode); - rtx ops[3] = {step_adj, vid, shift_amount}; insn_code icode = code_for_pred_scalar (ASHIFT, mode); - emit_binop (icode, ops, mask_mode, Pmode); + emit_nonvlmax_binop (icode, step_adj, vid, shift_amount, + NULL, mask_mode, Pmode); } else { - rtx ops[3] = {step_adj, vid, step}; insn_code icode = code_for_pred_scalar (MULT, mode); - emit_binop (icode, ops, mask_mode, inner_mode); + emit_nonvlmax_binop (icode, step_adj, vid, step, + NULL, mask_mode, inner_mode); } } @@ -346,9 +366,9 @@ expand_vec_series (rtx dest, rtx base, rtx step) else { rtx result = gen_reg_rtx (mode); - rtx ops[3] = {result, step_adj, base}; insn_code icode = code_for_pred_scalar (PLUS, mode); - emit_binop (icode, ops, mask_mode, inner_mode); + emit_nonvlmax_binop (icode, result, step_adj, base, + NULL, mask_mode, inner_mode); emit_move_insn (dest, result); } }