From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7928) id 88B943858D1E; Fri, 15 Sep 2023 12:59:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 88B943858D1E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1694782783; bh=T23OunoVQFOQIZoD7YG96ov8MHXE6kS4QuTxZZ73WH0=; h=From:To:Subject:Date:From; b=UG4RtLx9dSgXCUlT5KrzHvI1RJTwTqv0rQVRG8nKBktqH1lcpZZVsZR6FYlys7Xsf 7RPnIA9fqHnHb3xsGsgzOMLFBt8oQvb1RWEVElr0h6bXcG1Yudd9WrhlnMu2juugsw E7TfIUsxQxofnutkxgsuUF2DNXXD2gEpWOxtQN88= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Lehua Ding To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-4022] RISC-V: Fix using wrong mode to get reduction insn vlmax X-Act-Checkin: gcc X-Git-Author: Lehua Ding X-Git-Refname: refs/heads/trunk X-Git-Oldrev: e6dba708c8627080f4ca776590a191683b38336c X-Git-Newrev: dd6e5d29cbdbed25e4e52e5f06b1bfa835aab215 Message-Id: <20230915125943.88B943858D1E@sourceware.org> Date: Fri, 15 Sep 2023 12:59:43 +0000 (GMT) List-Id: https://gcc.gnu.org/g:dd6e5d29cbdbed25e4e52e5f06b1bfa835aab215 commit r14-4022-gdd6e5d29cbdbed25e4e52e5f06b1bfa835aab215 Author: Lehua Ding Date: Fri Sep 15 19:13:42 2023 +0800 RISC-V: Fix using wrong mode to get reduction insn vlmax This patch fix using wrong mode when emit vlmax reduction insn. We should use src operand instead dest operand (which always LMUL=m1) to get the vlmax length. This patch alse remove dest_mode and mask_mode from insn_expander constructor, which can be geted by insn_flags. gcc/ChangeLog: * config/riscv/riscv-protos.h (enum insn_flags): Change name. (enum insn_type): Ditto. * config/riscv/riscv-v.cc (get_mask_mode_from_insn_flags): Removed. (emit_vlmax_insn): Adjust. (emit_nonvlmax_insn): Adjust. (emit_vlmax_insn_lra): Adjust. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/vsetvl/wredsum_vlmax.c: New test. Diff: --- gcc/config/riscv/riscv-protos.h | 12 +-- gcc/config/riscv/riscv-v.cc | 87 ++++++++++------------ .../gcc.target/riscv/rvv/vsetvl/wredsum_vlmax.c | 15 ++++ 3 files changed, 60 insertions(+), 54 deletions(-) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index bb94a7e0441..5a2d218d67b 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -244,8 +244,8 @@ enum insn_flags : unsigned int /* Means INSN need two operands to do the operation. */ TERNARY_OP_P = 1 << 13, - /* flags for get mask mode from the index number. default from dest operand. */ - MASK_MODE_FROM_OP1_P = 1 << 14, + /* flags for get vtype mode from the index number. default from dest operand. */ + VTYPE_MODE_FROM_OP1_P = 1 << 14, /* flags for the floating-point rounding mode. */ /* Means INSN has FRM operand and the value is FRM_DYN. */ @@ -321,7 +321,7 @@ enum insn_type : unsigned int /* For vcpop.m, no merge operand, no tail and mask policy operands. */ CPOP_OP = HAS_DEST_P | HAS_MASK_P | USE_ALL_TRUES_MASK_P | UNARY_OP_P - | MASK_MODE_FROM_OP1_P, + | VTYPE_MODE_FROM_OP1_P, /* For mask instrunctions, no tail and mask policy operands. */ UNARY_MASK_OP = HAS_DEST_P | HAS_MASK_P | USE_ALL_TRUES_MASK_P | HAS_MERGE_P @@ -336,10 +336,10 @@ enum insn_type : unsigned int = HAS_DEST_P | HAS_MERGE_P | TDEFAULT_POLICY_P | BINARY_OP_P, /* For vreduce, no mask policy operand. */ - REDUCE_OP = __NORMAL_OP_TA | BINARY_OP_P | MASK_MODE_FROM_OP1_P, - REDUCE_OP_FRM_DYN = REDUCE_OP | FRM_DYN_P | MASK_MODE_FROM_OP1_P, + REDUCE_OP = __NORMAL_OP_TA | BINARY_OP_P | VTYPE_MODE_FROM_OP1_P, + REDUCE_OP_FRM_DYN = REDUCE_OP | FRM_DYN_P | VTYPE_MODE_FROM_OP1_P, REDUCE_OP_M_FRM_DYN - = __MASK_OP_TA | BINARY_OP_P | FRM_DYN_P | MASK_MODE_FROM_OP1_P, + = __MASK_OP_TA | BINARY_OP_P | FRM_DYN_P | VTYPE_MODE_FROM_OP1_P, /* For vmv.s.x/vfmv.s.f. */ SCALAR_MOVE_OP = HAS_DEST_P | HAS_MASK_P | USE_ONE_TRUE_MASK_P | HAS_MERGE_P diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 7e9fd9ec741..a9287e5d671 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -84,10 +84,9 @@ template class insn_expander public: insn_expander () = delete; - insn_expander (unsigned insn_flags, bool vlmax_p, machine_mode dest_mode, - machine_mode mask_mode) + insn_expander (unsigned insn_flags, bool vlmax_p) : m_insn_flags (insn_flags), m_opno (0), m_vlmax_p (vlmax_p), - m_dest_mode (dest_mode), m_mask_mode (mask_mode), m_vl_op (NULL_RTX) + m_vl_op (NULL_RTX) { check_insn_flags (); } @@ -150,13 +149,17 @@ public: create_input_operand (&m_ops[m_opno++], x, mode); gcc_assert (m_opno <= MAX_OPERANDS); } - void add_all_one_mask_operand () + void add_all_one_mask_operand (machine_mode mask_mode) { - add_input_operand (CONSTM1_RTX (m_mask_mode), m_mask_mode); + add_input_operand (CONSTM1_RTX (mask_mode), mask_mode); } - void add_vundef_operand () + void add_first_one_true_mask_operand (machine_mode mask_mode) { - add_input_operand (RVV_VUNDEF (m_dest_mode), m_dest_mode); + add_input_operand (gen_scalar_move_mask (mask_mode), mask_mode); + } + void add_vundef_operand (machine_mode dest_mode) + { + add_input_operand (RVV_VUNDEF (dest_mode), dest_mode); } void add_policy_operand () { @@ -194,9 +197,17 @@ public: add_input_operand (frm_rtx, Pmode); } - void add_oprand (rtx *ops, int opno) + /* Return the vtype mode based on insn_flags. + vtype mode mean the mode vsetvl insn set. */ + machine_mode + get_vtype_mode (rtx *ops) { - + machine_mode vtype_mode; + if (m_insn_flags & VTYPE_MODE_FROM_OP1_P) + vtype_mode = GET_MODE (ops[1]); + else + vtype_mode = GET_MODE (ops[0]); + return vtype_mode; } void emit_insn (enum insn_code icode, rtx *ops) @@ -206,18 +217,22 @@ public: /* It's true if any operand is memory operand. */ bool any_mem_p = false; + machine_mode vtype_mode = get_vtype_mode (ops); + machine_mode mask_mode = get_mask_mode (vtype_mode); + /* Add dest operand. */ if (m_insn_flags & HAS_DEST_P) { - any_mem_p |= MEM_P (ops[opno]); - add_output_operand (ops[opno++], m_dest_mode); + rtx op = ops[opno++]; + any_mem_p |= MEM_P (op); + add_output_operand (op, GET_MODE (op)); } /* Add mask operand. */ if (m_insn_flags & USE_ONE_TRUE_MASK_P) - add_input_operand (gen_scalar_move_mask (m_mask_mode), m_mask_mode); + add_first_one_true_mask_operand (mask_mode); else if (m_insn_flags & USE_ALL_TRUES_MASK_P) - add_all_one_mask_operand (); + add_all_one_mask_operand (mask_mode); else if (m_insn_flags & HAS_MASK_P) { machine_mode mode = insn_data[(int) icode].operand[m_opno].mode; @@ -227,7 +242,8 @@ public: /* Add merge operand. */ if (m_insn_flags & USE_VUNDEF_MERGE_P) - add_vundef_operand (); + /* Same as dest operand. */ + add_vundef_operand (GET_MODE (ops[0])); else if (m_insn_flags & HAS_MERGE_P) { machine_mode mode = insn_data[(int) icode].operand[m_opno].mode; @@ -268,31 +284,30 @@ public: /* Add vl operand. */ rtx len = m_vl_op; - machine_mode mode = VECTOR_MODE_P (m_dest_mode) ? m_dest_mode : m_mask_mode; if (m_vlmax_p) { - if (riscv_v_ext_vls_mode_p (mode)) + if (riscv_v_ext_vls_mode_p (vtype_mode)) { /* VLS modes always set VSETVL by "vsetvl zero, rs1/imm". */ - poly_uint64 nunits = GET_MODE_NUNITS (mode); + poly_uint64 nunits = GET_MODE_NUNITS (vtype_mode); len = gen_int_mode (nunits, Pmode); if (!satisfies_constraint_K (len)) len = force_reg (Pmode, len); m_vlmax_p = false; } - else if (const_vlmax_p (mode)) + else if (const_vlmax_p (vtype_mode)) { /* Optimize VLS-VLMAX code gen, we can use vsetivli instead of the vsetvli to obtain the value of vlmax. */ - poly_uint64 nunits = GET_MODE_NUNITS (mode); + poly_uint64 nunits = GET_MODE_NUNITS (vtype_mode); len = gen_int_mode (nunits, Pmode); m_vlmax_p = false; } else if (can_create_pseudo_p ()) { len = gen_reg_rtx (Pmode); - emit_vlmax_vsetvl (mode, len); + emit_vlmax_vsetvl (vtype_mode, len); } } @@ -325,38 +340,20 @@ public: } private: - int m_insn_flags; + unsigned m_insn_flags; int m_opno; bool m_vlmax_p; - machine_mode m_dest_mode; - machine_mode m_mask_mode; rtx m_vl_op; expand_operand m_ops[MAX_OPERANDS]; }; -/* Return the mask mode based on insn_flags */ -static machine_mode -get_mask_mode_from_insn_flags (unsigned insn_flags, rtx *ops) -{ - machine_mode mask_mode; - if (insn_flags & MASK_MODE_FROM_OP1_P) - mask_mode = get_mask_mode (GET_MODE (ops[1])); - else - mask_mode = get_mask_mode (GET_MODE (ops[0])); - return mask_mode; -} - /* Emit RVV insn which vl is VLMAX. This function can only be used before LRA pass or for VLS_AVL_IMM modes. */ void emit_vlmax_insn (unsigned icode, unsigned insn_flags, rtx *ops) { - machine_mode dest_mode = GET_MODE (ops[0]); - machine_mode mask_mode = get_mask_mode_from_insn_flags (insn_flags, ops); - - insn_expander e (insn_flags, true, dest_mode, - mask_mode); + insn_expander e (insn_flags, true); e.emit_insn ((enum insn_code) icode, ops); } @@ -364,10 +361,7 @@ emit_vlmax_insn (unsigned icode, unsigned insn_flags, rtx *ops) void emit_nonvlmax_insn (unsigned icode, unsigned insn_flags, rtx *ops, rtx vl) { - machine_mode dest_mode = GET_MODE (ops[0]); - machine_mode mask_mode = get_mask_mode_from_insn_flags (insn_flags, ops); - insn_expander e (insn_flags, false, dest_mode, - mask_mode); + insn_expander e (insn_flags, false); e.set_vl (vl); e.emit_insn ((enum insn_code) icode, ops); } @@ -379,10 +373,7 @@ emit_vlmax_insn_lra (unsigned icode, unsigned insn_flags, rtx *ops, rtx vl) { gcc_assert (!can_create_pseudo_p ()); - machine_mode dest_mode = GET_MODE (ops[0]); - machine_mode mask_mode = get_mask_mode_from_insn_flags (insn_flags, ops); - insn_expander e (insn_flags, true, dest_mode, - mask_mode); + insn_expander e (insn_flags, true); e.set_vl (vl); e.emit_insn ((enum insn_code) icode, ops); } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/wredsum_vlmax.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/wredsum_vlmax.c new file mode 100644 index 00000000000..6b7c77326ae --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/wredsum_vlmax.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv_zvl256b --param=riscv-autovec-preference=fixed-vlmax -O3" } */ + + +#include + +int16_t foo (int8_t *restrict a) +{ + int16_t sum = 0; + for (int i = 0; i < 8; i += 1) + sum += a[i]; + return sum; +} + +/* { dg-final { scan-assembler-not {\tvsetivli\tzero,16} } } */