diff options
-rw-r--r-- | gcc/config/riscv/riscv-protos.h | 12 | ||||
-rw-r--r-- | gcc/config/riscv/riscv-v.cc | 87 | ||||
-rw-r--r-- | gcc/testsuite/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 bb94a7e..5a2d218 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 7e9fd9e..a9287e5 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -84,10 +84,9 @@ template <int MAX_OPERANDS> 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<RVV_INSN_OPERANDS_MAX> e (insn_flags, true, dest_mode, - mask_mode); + insn_expander<RVV_INSN_OPERANDS_MAX> 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<RVV_INSN_OPERANDS_MAX> e (insn_flags, false, dest_mode, - mask_mode); + insn_expander<RVV_INSN_OPERANDS_MAX> 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<RVV_INSN_OPERANDS_MAX> e (insn_flags, true, dest_mode, - mask_mode); + insn_expander<RVV_INSN_OPERANDS_MAX> 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 0000000..6b7c773 --- /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 <stdint.h> + +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} } } */ |