From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-ed1-x52a.google.com with SMTP id 4fb4d7f45d1cf-50bc4b88998so14871550a12.3 for ; Thu, 11 May 2023 03:26:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; 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 :from:to:cc:subject:date:message-id:reply-to; bh=XmfZNzjM0Pc0wuQ3p2N+HgVbeGEvhMMW9nGaNb9PPT8=; b=EMC4RVswh6mMEDkHG9uJw8rSqjxu8cDlDT+7pfva2RhmcNcLl78tpQnQeoiyAcdeg9 hHpsJxpDmJF0jC//+m6DxCnqsPea0kaDTqZu5exH3g/bhqDzGb1xl22KVKIC5G8g2nSR TD3QdCCEpoZeXUjaWP46AGnEPIkDaXJ7KIV0H+s6dsSqWHhnvjc6iO9xUqV/D74pP8Bo pUKoPviF+pSR8fz/w9XvX4OoUUy4b9aJWXefzi9Olc6/3ybSRD3D8xaCzfytIVjpwwWN RgomKWMoXmPCxs0syZoplEmfLj1rbWauz9CYIovlvRwxUjQ2xygNrRov8ZECoCSPJjMw iipQ== 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-Google-Smtp-Source: ACHHUZ5t/IjLKwaUJLaPq3uf00L7+LwteccQuTe/HUDskkSM9Iy5jRPtvp7T9nX0v6vPcoKNUTkOkg== 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> From: Robin Dapp Cc: rdapp.gcc@gmail.com In-Reply-To: <26EA7AD78CFB10DB+2023051106550856361413@rivai.ai> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit 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 List-Id: 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); } } -- 2.40.0