[PATCH 0/5] RISC-V: Support vf and vx for autovec comparison of
We expect: flw ... vmfxx.vf For simplicity of supporting vx and vf, two refactors completed first. 1. remove eqne pattern; any special case or reason for eqne when first added? 2. refactor duplicate code. demin.han (5): RISC-V: Remove float vector eqne pattern RISC-V: Refactor expand_vec_cmp RISC-V: Support vmfxx.vf for autovec comparison of vec and imm RISC-V: Remove integer vector eqne pattern RISC-V: Support vmsxx.vx for autovec comparison of vec and imm gcc/config/riscv/autovec.md | 2 +- gcc/config/riscv/predicates.md| 4 +- gcc/config/riscv/riscv-protos.h | 2 +- gcc/config/riscv/riscv-string.cc | 4 +- gcc/config/riscv/riscv-v.cc | 94 ++--- .../riscv/riscv-vector-builtins-bases.cc | 7 - gcc/config/riscv/riscv.cc | 2 +- gcc/config/riscv/vector.md| 365 +- .../riscv/rvv/autovec/cmp/vcond-1.c | 48 ++- 9 files changed, 105 insertions(+), 423 deletions(-) -- 2.43.2
[PATCH 1/5] RISC-V: Remove float vector eqne pattern
We can unify eqne and other comparison operations. Tested on RV32 and RV64 gcc/ChangeLog: * config/riscv/riscv-vector-builtins-bases.cc: Remove eqne cond * config/riscv/vector.md (@pred_eqne_scalar): Remove patterns (*pred_eqne_scalar_merge_tie_mask): Ditto (*pred_eqne_scalar): Ditto (*pred_eqne_scalar_narrow): Ditto Signed-off-by: demin.han --- .../riscv/riscv-vector-builtins-bases.cc | 4 - gcc/config/riscv/vector.md| 86 --- 2 files changed, 90 deletions(-) diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index b6f6e4ff37e..d414721ede8 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -1420,10 +1420,6 @@ public: switch (e.op_info->op) { case OP_TYPE_vf: { - if (CODE == EQ || CODE == NE) - return e.use_compare_insn (CODE, code_for_pred_eqne_scalar ( - e.vector_mode ())); - else return e.use_compare_insn (CODE, code_for_pred_cmp_scalar ( e.vector_mode ())); } diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index ab6e099852d..9210d7c28ad 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -7520,92 +7520,6 @@ (define_insn "*pred_cmp_scalar_narrow" (set_attr "mode" "") (set_attr "spec_restriction" "none,thv,thv,none,none")]) -(define_expand "@pred_eqne_scalar" - [(set (match_operand: 0 "register_operand") - (if_then_else: - (unspec: - [(match_operand: 1 "vector_mask_operand") -(match_operand 6 "vector_length_operand") -(match_operand 7 "const_int_operand") -(match_operand 8 "const_int_operand") -(reg:SI VL_REGNUM) -(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operator: 3 "equality_operator" -[(vec_duplicate:V_VLSF - (match_operand: 5 "register_operand")) - (match_operand:V_VLSF 4 "register_operand")]) - (match_operand: 2 "vector_merge_operand")))] - "TARGET_VECTOR" - {}) - -(define_insn "*pred_eqne_scalar_merge_tie_mask" - [(set (match_operand: 0 "register_operand" "=vm") - (if_then_else: - (unspec: - [(match_operand: 1 "register_operand" " 0") -(match_operand 5 "vector_length_operand" " rK") -(match_operand 6 "const_int_operand" " i") -(match_operand 7 "const_int_operand" " i") -(reg:SI VL_REGNUM) -(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operator: 2 "equality_operator" -[(vec_duplicate:V_VLSF - (match_operand: 4 "register_operand" " f")) - (match_operand:V_VLSF 3 "register_operand" " vr")]) - (match_dup 1)))] - "TARGET_VECTOR" - "vmf%B2.vf\t%0,%3,%4,v0.t" - [(set_attr "type" "vfcmp") - (set_attr "mode" "") - (set_attr "merge_op_idx" "1") - (set_attr "vl_op_idx" "5") - (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])")) - (set (attr "avl_type_idx") (const_int 7))]) - -;; We don't use early-clobber for LMUL <= 1 to get better codegen. -(define_insn "*pred_eqne_scalar" - [(set (match_operand: 0 "register_operand""=vr, vr, &vr, &vr") - (if_then_else: - (unspec: - [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1,vmWc1,vmWc1") -(match_operand 6 "vector_length_operand" " rK, rK, rK, rK") -(match_operand 7 "const_int_operand" "i,i, i,i") -(match_operand 8 "const_int_operand" "i,i, i,i") -(reg:SI VL_REGNUM) -(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operator: 3 "equality_operator" -[(vec_duplicate:V_VLSF - (match_operand: 5 "register_operand" "f,f, f,f")) - (match_operand:V_VLSF 4 "register_operand" " vr, vr, vr, vr")]) - (match_operand: 2 "vector_merge_operand""
[PATCH 5/5] RISC-V: Support vmsxx.vx for autovec comparison of vec and imm
Similar to previous float change, vmsxx.vx is needed. 1. Only those which can't match vi should use vx. 2. DImode is processed by sew64_scalar_helper. Tested on RV32 and RV64. gcc/ChangeLog: * config/riscv/riscv-v.cc (get_cmp_insn_code): Select scalar pattern (expand_vec_cmp): Ditto gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/cmp/vcond-1.c: Update expect Signed-off-by: demin.han --- gcc/config/riscv/riscv-v.cc | 33 --- .../riscv/rvv/autovec/cmp/vcond-1.c | 14 ++-- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 2a188ac78e0..9b601a4a8ff 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -2619,26 +2619,18 @@ get_cmp_insn_code (rtx_code code, machine_mode mode, bool scalar_p) : code_for_pred_cmp_scalar (mode); return icode; } - switch (code) + if (scalar_p) { -case EQ: -case NE: -case LE: -case LEU: -case GT: -case GTU: -case LTGT: - icode = code_for_pred_cmp (mode); - break; -case LT: -case LTU: -case GE: -case GEU: - icode = code_for_pred_ltge (mode); - break; -default: - gcc_unreachable (); + if (code == GE || code == GEU) + icode = code_for_pred_ge_scalar (mode); + else + icode = code_for_pred_cmp_scalar (mode); + return icode; } + if (code == LT || code == LTU || code == GE || code == GEU) +icode = code_for_pred_ltge (mode); + else +icode = code_for_pred_cmp (mode); return icode; } @@ -2775,7 +2767,10 @@ expand_vec_cmp (rtx target, rtx_code code, rtx op0, rtx op1, rtx mask, rtx elt; machine_mode scalar_mode = GET_MODE_INNER (GET_MODE (op1)); - bool scalar_p = const_vec_duplicate_p (op1, &elt) && FLOAT_MODE_P (data_mode); + bool scalar_p += const_vec_duplicate_p (op1, &elt) + && (FLOAT_MODE_P (data_mode) + || (scalar_mode != DImode && !has_vi_variant_p (code, elt))); if (scalar_p) op1 = force_reg (scalar_mode, elt); insn_code icode = get_cmp_insn_code (code, data_mode, scalar_p); diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-1.c index 7f6738518ee..e04c2a0cfbd 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-1.c @@ -180,9 +180,19 @@ TEST_IMM_FLOAT_ALL (DEF_VCOND_IMM) /* { dg-final { scan-assembler-times {\tvmseq} 78 } } */ /* { dg-final { scan-assembler-times {\tvmsne} 78 } } */ /* { dg-final { scan-assembler-times {\tvmsgt} 82 } } */ -/* { dg-final { scan-assembler-times {\tvmslt} 38 } } */ -/* { dg-final { scan-assembler-times {\tvmsge} 38 } } */ +/* { dg-final { scan-assembler-times {\tvmslt} 50 } } */ +/* { dg-final { scan-assembler-times {\tvmsge} 26 } } */ /* { dg-final { scan-assembler-times {\tvmsle} 82 } } */ +/* { dg-final { scan-assembler-times {\tvmseq\.vx} 16 } } */ +/* { dg-final { scan-assembler-times {\tvmsne\.vx} 16 } } */ +/* { dg-final { scan-assembler-times {\tvmsgt\.vx} 4 } } */ +/* { dg-final { scan-assembler-times {\tvmsgtu\.vx} 14 } } */ +/* { dg-final { scan-assembler-times {\tvmslt\.vx} 24 } } */ +/* { dg-final { scan-assembler-times {\tvmsltu\.vx} 0 } } */ +/* { dg-final { scan-assembler-times {\tvmsge\.vx} 0 } } */ +/* { dg-final { scan-assembler-times {\tvmsgeu\.vx} 0 } } */ +/* { dg-final { scan-assembler-times {\tvmsle\.vx} 4 } } */ +/* { dg-final { scan-assembler-times {\tvmsleu\.vx} 14 } } */ /* { dg-final { scan-assembler-times {\tvmfgt.vf} 6 } } */ /* { dg-final { scan-assembler-times {\tvmflt.vf} 6 } } */ /* { dg-final { scan-assembler-times {\tvmfge.vf} 6 } } */ -- 2.43.2
[PATCH 2/5] RISC-V: Refactor expand_vec_cmp
There are two expand_vec_cmp functions. They have same structure and similar code. We can use default arguments instead of overloading. Tested on RV32 and RV64. gcc/ChangeLog: * config/riscv/riscv-protos.h (expand_vec_cmp): Change proto * config/riscv/riscv-v.cc (expand_vec_cmp): Use default arguments (expand_vec_cmp_float): Adapt arguments Signed-off-by: demin.han --- gcc/config/riscv/riscv-protos.h | 2 +- gcc/config/riscv/riscv-v.cc | 44 +++-- 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 80efdf2b7e5..b8735593805 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -603,7 +603,7 @@ bool simm5_p (rtx); bool neg_simm5_p (rtx); #ifdef RTX_CODE bool has_vi_variant_p (rtx_code, rtx); -void expand_vec_cmp (rtx, rtx_code, rtx, rtx); +void expand_vec_cmp (rtx, rtx_code, rtx, rtx, rtx = nullptr, rtx = nullptr); bool expand_vec_cmp_float (rtx, rtx_code, rtx, rtx, bool); void expand_cond_len_unop (unsigned, rtx *); void expand_cond_len_binop (unsigned, rtx *); diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 0cfbd21ce6f..14e75b9a117 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -2752,7 +2752,8 @@ vectorize_related_mode (machine_mode vector_mode, scalar_mode element_mode, /* Expand an RVV comparison. */ void -expand_vec_cmp (rtx target, rtx_code code, rtx op0, rtx op1) +expand_vec_cmp (rtx target, rtx_code code, rtx op0, rtx op1, rtx mask, + rtx maskoff) { machine_mode mask_mode = GET_MODE (target); machine_mode data_mode = GET_MODE (op0); @@ -2762,8 +2763,8 @@ expand_vec_cmp (rtx target, rtx_code code, rtx op0, rtx op1) { rtx lt = gen_reg_rtx (mask_mode); rtx gt = gen_reg_rtx (mask_mode); - expand_vec_cmp (lt, LT, op0, op1); - expand_vec_cmp (gt, GT, op0, op1); + expand_vec_cmp (lt, LT, op0, op1, mask, maskoff); + expand_vec_cmp (gt, GT, op0, op1, mask, maskoff); icode = code_for_pred (IOR, mask_mode); rtx ops[] = {target, lt, gt}; emit_vlmax_insn (icode, BINARY_MASK_OP, ops); @@ -2771,33 +2772,16 @@ expand_vec_cmp (rtx target, rtx_code code, rtx op0, rtx op1) } rtx cmp = gen_rtx_fmt_ee (code, mask_mode, op0, op1); - rtx ops[] = {target, cmp, op0, op1}; - emit_vlmax_insn (icode, COMPARE_OP, ops); -} - -void -expand_vec_cmp (rtx target, rtx_code code, rtx mask, rtx maskoff, rtx op0, - rtx op1) -{ - machine_mode mask_mode = GET_MODE (target); - machine_mode data_mode = GET_MODE (op0); - insn_code icode = get_cmp_insn_code (code, data_mode); - - if (code == LTGT) + if (!mask && !maskoff) { - rtx lt = gen_reg_rtx (mask_mode); - rtx gt = gen_reg_rtx (mask_mode); - expand_vec_cmp (lt, LT, mask, maskoff, op0, op1); - expand_vec_cmp (gt, GT, mask, maskoff, op0, op1); - icode = code_for_pred (IOR, mask_mode); - rtx ops[] = {target, lt, gt}; - emit_vlmax_insn (icode, BINARY_MASK_OP, ops); - return; + rtx ops[] = {target, cmp, op0, op1}; + emit_vlmax_insn (icode, COMPARE_OP, ops); +} + else +{ + rtx ops[] = {target, mask, maskoff, cmp, op0, op1}; + emit_vlmax_insn (icode, COMPARE_OP_MU, ops); } - - rtx cmp = gen_rtx_fmt_ee (code, mask_mode, op0, op1); - rtx ops[] = {target, mask, maskoff, cmp, op0, op1}; - emit_vlmax_insn (icode, COMPARE_OP_MU, ops); } /* Expand an RVV floating-point comparison: @@ -2875,7 +2859,7 @@ expand_vec_cmp_float (rtx target, rtx_code code, rtx op0, rtx op1, else { /* vmfeq.vvv0, vb, vb, v0.t */ - expand_vec_cmp (eq0, EQ, eq0, eq0, op1, op1); + expand_vec_cmp (eq0, EQ, op1, op1, eq0, eq0); } break; default: @@ -2893,7 +2877,7 @@ expand_vec_cmp_float (rtx target, rtx_code code, rtx op0, rtx op1, if (code == ORDERED) emit_move_insn (target, eq0); else -expand_vec_cmp (eq0, code, eq0, eq0, op0, op1); +expand_vec_cmp (eq0, code, op0, op1, eq0, eq0); if (can_invert_p) { -- 2.43.2
[PATCH 3/5] RISC-V: Support vmfxx.vf for autovec comparison of vec and imm
Currently, following instructions generated in autovector: flw vsetvli vfmv.v.f ... vmfxx.vv Two issues: 1. Additional vsetvl and vfmv instructions 2. Occupy one vector register and may results in smaller lmul We expect: flw ... vmfxx.vf Tested on RV32 and RV64 gcc/ChangeLog: * config/riscv/autovec.md: Accept imm * config/riscv/riscv-v.cc (get_cmp_insn_code): Select scalar pattern (expand_vec_cmp): Ditto * config/riscv/riscv.cc (riscv_const_insns): Exclude float mode gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/cmp/vcond-1.c: Add new tests Signed-off-by: demin.han --- gcc/config/riscv/autovec.md | 2 +- gcc/config/riscv/riscv-v.cc | 23 + gcc/config/riscv/riscv.cc | 2 +- .../riscv/rvv/autovec/cmp/vcond-1.c | 34 +++ 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index 3b32369f68c..6cfb0800c45 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -690,7 +690,7 @@ (define_expand "vec_cmp" [(set (match_operand: 0 "register_operand") (match_operator: 1 "comparison_operator" [(match_operand:V_VLSF 2 "register_operand") - (match_operand:V_VLSF 3 "register_operand")]))] + (match_operand:V_VLSF 3 "nonmemory_operand")]))] "TARGET_VECTOR" { riscv_vector::expand_vec_cmp_float (operands[0], GET_CODE (operands[1]), diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 14e75b9a117..2a188ac78e0 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -2610,9 +2610,15 @@ expand_vec_init (rtx target, rtx vals) /* Get insn code for corresponding comparison. */ static insn_code -get_cmp_insn_code (rtx_code code, machine_mode mode) +get_cmp_insn_code (rtx_code code, machine_mode mode, bool scalar_p) { insn_code icode; + if (FLOAT_MODE_P (mode)) +{ + icode = !scalar_p ? code_for_pred_cmp (mode) + : code_for_pred_cmp_scalar (mode); + return icode; +} switch (code) { case EQ: @@ -2628,10 +2634,7 @@ get_cmp_insn_code (rtx_code code, machine_mode mode) case LTU: case GE: case GEU: - if (FLOAT_MODE_P (mode)) - icode = code_for_pred_cmp (mode); - else - icode = code_for_pred_ltge (mode); + icode = code_for_pred_ltge (mode); break; default: gcc_unreachable (); @@ -2757,7 +2760,6 @@ expand_vec_cmp (rtx target, rtx_code code, rtx op0, rtx op1, rtx mask, { machine_mode mask_mode = GET_MODE (target); machine_mode data_mode = GET_MODE (op0); - insn_code icode = get_cmp_insn_code (code, data_mode); if (code == LTGT) { @@ -2765,12 +2767,19 @@ expand_vec_cmp (rtx target, rtx_code code, rtx op0, rtx op1, rtx mask, rtx gt = gen_reg_rtx (mask_mode); expand_vec_cmp (lt, LT, op0, op1, mask, maskoff); expand_vec_cmp (gt, GT, op0, op1, mask, maskoff); - icode = code_for_pred (IOR, mask_mode); + insn_code icode = code_for_pred (IOR, mask_mode); rtx ops[] = {target, lt, gt}; emit_vlmax_insn (icode, BINARY_MASK_OP, ops); return; } + rtx elt; + machine_mode scalar_mode = GET_MODE_INNER (GET_MODE (op1)); + bool scalar_p = const_vec_duplicate_p (op1, &elt) && FLOAT_MODE_P (data_mode); + if (scalar_p) +op1 = force_reg (scalar_mode, elt); + insn_code icode = get_cmp_insn_code (code, data_mode, scalar_p); + rtx cmp = gen_rtx_fmt_ee (code, mask_mode, op0, op1); if (!mask && !maskoff) { diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 4100abc9dd1..1ffe4865c19 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -1760,7 +1760,7 @@ riscv_const_insns (rtx x) register vec_duplicate into vmv.v.x. */ scalar_mode smode = GET_MODE_INNER (GET_MODE (x)); if (maybe_gt (GET_MODE_SIZE (smode), UNITS_PER_WORD) - && !immediate_operand (elt, Pmode)) + && !FLOAT_MODE_P (smode) && !immediate_operand (elt, Pmode)) return 0; /* Constants from -16 to 15 can be loaded with vmv.v.i. The Wc0, Wc1 constraints are already covered by the diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-1.c index 99a230d1c8a..7f6738518ee 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cmp/vcond-1.c @@ -141,6 +141,34 @@ TEST_VAR_ALL (DEF_VCOND_VAR) TEST_IMM_ALL (DEF_VCOND_IMM) +#define TEST_COND_IMM_FLOAT(T, COND, IMM, SUFFIX) \
[PATCH 4/5] RISC-V: Remove integer vector eqne pattern
We can unify eqne and other comparison operations. Tested on RV32 and RV64. gcc/ChangeLog: * config/riscv/predicates.md (comparison_except_eqge_operator): Only exclue ge (comparison_except_ge_operator): Ditto * config/riscv/riscv-string.cc (expand_rawmemchr): Use cmp pattern (expand_strcmp): Ditto * config/riscv/riscv-vector-builtins-bases.cc: Remvoe eqne cond * config/riscv/vector.md (@pred_eqne_scalar): Remove eqne patterns (*pred_eqne_scalar_merge_tie_mask): Ditto (*pred_eqne_scalar): Ditto (*pred_eqne_scalar_narrow): Ditto (*pred_eqne_extended_scalar_merge_tie_mask): Ditto (*pred_eqne_extended_scalar): Ditto (*pred_eqne_extended_scalar_narrow): Ditto Signed-off-by: demin.han --- gcc/config/riscv/predicates.md| 4 +- gcc/config/riscv/riscv-string.cc | 4 +- .../riscv/riscv-vector-builtins-bases.cc | 3 - gcc/config/riscv/vector.md| 279 +- 4 files changed, 15 insertions(+), 275 deletions(-) diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 6c87a7bd1f4..7f144551bb2 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -548,8 +548,8 @@ (define_predicate "ltge_operator" (define_predicate "comparison_except_ltge_operator" (match_code "eq,ne,le,leu,gt,gtu")) -(define_predicate "comparison_except_eqge_operator" - (match_code "le,leu,gt,gtu,lt,ltu")) +(define_predicate "comparison_except_ge_operator" + (match_code "eq,ne,le,leu,gt,gtu,lt,ltu")) (define_predicate "ge_operator" (match_code "ge,geu")) diff --git a/gcc/config/riscv/riscv-string.cc b/gcc/config/riscv/riscv-string.cc index b09b51d7526..da33bd74ac6 100644 --- a/gcc/config/riscv/riscv-string.cc +++ b/gcc/config/riscv/riscv-string.cc @@ -1074,7 +1074,7 @@ expand_rawmemchr (machine_mode mode, rtx dst, rtx haystack, rtx needle, /* Compare needle with haystack and store in a mask. */ rtx eq = gen_rtx_EQ (mask_mode, gen_const_vec_duplicate (vmode, needle), vec); rtx vmsops[] = {mask, eq, vec, needle}; - emit_nonvlmax_insn (code_for_pred_eqne_scalar (vmode), + emit_nonvlmax_insn (code_for_pred_cmp_scalar (vmode), riscv_vector::COMPARE_OP, vmsops, cnt); /* Find the first bit in the mask. */ @@ -1200,7 +1200,7 @@ expand_strcmp (rtx result, rtx src1, rtx src2, rtx nbytes, = gen_rtx_EQ (mask_mode, gen_const_vec_duplicate (vmode, CONST0_RTX (mode)), vec1); rtx vmsops1[] = {mask0, eq0, vec1, CONST0_RTX (mode)}; - emit_nonvlmax_insn (code_for_pred_eqne_scalar (vmode), + emit_nonvlmax_insn (code_for_pred_cmp_scalar (vmode), riscv_vector::COMPARE_OP, vmsops1, cnt); /* Look for vec1 != vec2 (includes vec2[i] == 0). */ diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index d414721ede8..0cef0b91758 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -718,9 +718,6 @@ public: if (CODE == GE || CODE == GEU) return e.use_compare_insn (CODE, code_for_pred_ge_scalar ( e.vector_mode ())); - else if (CODE == EQ || CODE == NE) - return e.use_compare_insn (CODE, code_for_pred_eqne_scalar ( - e.vector_mode ())); else return e.use_compare_insn (CODE, code_for_pred_cmp_scalar ( e.vector_mode ())); diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index 9210d7c28ad..544ca4af938 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -4671,7 +4671,7 @@ (define_expand "@pred_cmp_scalar" (match_operand 8 "const_int_operand") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operator: 3 "comparison_except_eqge_operator" + (match_operator: 3 "comparison_except_ge_operator" [(match_operand:V_VLSI_QHS 4 "register_operand") (vec_duplicate:V_VLSI_QHS (match_operand: 5 "register_operand"))]) @@ -4689,7 +4689,7 @@ (define_insn "*pred_cmp_scalar_merge_tie_mask" (match_operand 7 "const_int_operand" " i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operator: 2 "comparison_except_eqge_operator" + (match_operator: 2 "comparison_except_ge_operator" [(match_operand:V_VLSI_QHS 3 "register_operand" " vr") (vec_duplicate:
[PATCH] MAINTAINERS: Add myself to write after approval
ChangeLog: * MAINTAINERS: Add myself Signed-off-by: demin.han --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index b01fab16061..a681518d704 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -448,6 +448,7 @@ Wei Guozhi Vineet Gupta Naveen H.S Mostafa Hagog +Demin Han Jivan Hakobyan Andrew Haley Frederik Harwath -- 2.43.2
[PATCH] RISC-V: Fix ICE in riscv vector costs
The following code can result in ICE: -march=rv64gcv_zba_zbb --param riscv-autovec-lmul=dynamic -O3 char *jpeg_difference7_input_buf; void jpeg_difference7(int *diff_buf) { unsigned width; int samp, Rb; while (--width) { Rb = samp = *jpeg_difference7_input_buf; *diff_buf++ = -(int)(samp + (long)Rb >> 1); } } One biggest_mode update missed in one branch and trigger assertion fail. gcc_assert (biggest_size >= mode_size); Tested On RV64 and no regression. gcc/ChangeLog: * config/riscv/riscv-vector-costs.cc: Fix ICE Signed-off-by: demin.han --- gcc/config/riscv/riscv-vector-costs.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcc/config/riscv/riscv-vector-costs.cc b/gcc/config/riscv/riscv-vector-costs.cc index 7c9840df4e9..f13a1296b31 100644 --- a/gcc/config/riscv/riscv-vector-costs.cc +++ b/gcc/config/riscv/riscv-vector-costs.cc @@ -413,6 +413,8 @@ compute_local_live_ranges ( auto *r = get_live_range (live_ranges, arg); gcc_assert (r); (*r).second = MAX (point, (*r).second); + biggest_mode = get_biggest_mode ( + biggest_mode, TYPE_MODE (TREE_TYPE (arg))); } } else -- 2.44.0
[PATCH v2] RISC-V: Fix ICE in riscv vector costs
The following code can result in ICE: -march=rv64gcv --param riscv-autovec-lmul=dynamic -O3 char *jpeg_difference7_input_buf; void jpeg_difference7(int *diff_buf) { unsigned width; int samp, Rb; while (--width) { Rb = samp = *jpeg_difference7_input_buf; *diff_buf++ = -(int)(samp + (long)Rb >> 1); } } One biggest_mode update missed in one branch and trigger assertion fail. gcc_assert (biggest_size >= mode_size); Tested On RV64 and no regression. PR 114264 gcc/ChangeLog: * config/riscv/riscv-vector-costs.cc: Fix ICE gcc/testsuite/ChangeLog: * gcc.dg/vect/costmodel/riscv/rvv/pr114264.c: New test. Signed-off-by: demin.han --- gcc/config/riscv/riscv-vector-costs.cc| 2 ++ .../gcc.dg/vect/costmodel/riscv/rvv/pr114264.c| 15 +++ 2 files changed, 17 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr114264.c diff --git a/gcc/config/riscv/riscv-vector-costs.cc b/gcc/config/riscv/riscv-vector-costs.cc index 7c9840df4e9..f13a1296b31 100644 --- a/gcc/config/riscv/riscv-vector-costs.cc +++ b/gcc/config/riscv/riscv-vector-costs.cc @@ -413,6 +413,8 @@ compute_local_live_ranges ( auto *r = get_live_range (live_ranges, arg); gcc_assert (r); (*r).second = MAX (point, (*r).second); + biggest_mode = get_biggest_mode ( + biggest_mode, TYPE_MODE (TREE_TYPE (arg))); } } else diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr114264.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr114264.c new file mode 100644 index 000..7853f292af7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr114264.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize --param=riscv-autovec-lmul=dynamic" } */ + +char *jpeg_difference7_input_buf; +void +jpeg_difference7 (int *diff_buf) +{ + unsigned width; + int samp, Rb; + while (--width) +{ + Rb = samp = *jpeg_difference7_input_buf; + *diff_buf++ = -(int) (samp + (long) Rb >> 1); +} +} -- 2.44.0
[PATCH] RISC-V: Refine the condition for add additional vars in RVV cost model
The adjacent_dr_p is sufficient and unnecessary condition for contiguous access. So unnecessary live-ranges are added and result in spill. This patch uses MEMORY_ACCESS_TYPE as condition and constrains segment load/store. Tested on RV64 and no regression. PR target/114506 gcc/ChangeLog: * config/riscv/riscv-vector-costs.cc (non_contiguous_memory_access_p): Rename (need_additional_vector_vars_p): Rename and refine condition gcc/testsuite/ChangeLog: * gcc.dg/vect/costmodel/riscv/rvv/pr114506.c: New test. Signed-off-by: demin.han --- gcc/config/riscv/riscv-vector-costs.cc| 25 --- .../vect/costmodel/riscv/rvv/pr114506.c | 23 + 2 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr114506.c diff --git a/gcc/config/riscv/riscv-vector-costs.cc b/gcc/config/riscv/riscv-vector-costs.cc index f462c272a6e..9f7fe936a29 100644 --- a/gcc/config/riscv/riscv-vector-costs.cc +++ b/gcc/config/riscv/riscv-vector-costs.cc @@ -563,14 +563,24 @@ get_store_value (gimple *stmt) return gimple_assign_rhs1 (stmt); } -/* Return true if it is non-contiguous load/store. */ +/* Return true if addtional vector vars needed. */ static bool -non_contiguous_memory_access_p (stmt_vec_info stmt_info) +need_additional_vector_vars_p (stmt_vec_info stmt_info) { enum stmt_vec_info_type type = STMT_VINFO_TYPE (vect_stmt_to_vectorize (stmt_info)); - return ((type == load_vec_info_type || type == store_vec_info_type) - && !adjacent_dr_p (STMT_VINFO_DATA_REF (stmt_info))); + if (type == load_vec_info_type || type == store_vec_info_type) +{ + if (STMT_VINFO_GATHER_SCATTER_P (stmt_info) + && STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) == VMAT_GATHER_SCATTER) + return true; + + machine_mode mode = TYPE_MODE (STMT_VINFO_VECTYPE (stmt_info)); + int lmul = riscv_get_v_regno_alignment (mode); + if (DR_GROUP_SIZE (stmt_info) * lmul > RVV_M8) + return true; +} + return false; } /* Return the LMUL of the current analysis. */ @@ -739,10 +749,7 @@ update_local_live_ranges ( stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (si)); enum stmt_vec_info_type type = STMT_VINFO_TYPE (vect_stmt_to_vectorize (stmt_info)); - if (non_contiguous_memory_access_p (stmt_info) - /* LOAD_LANES/STORE_LANES doesn't need a perm indice. */ - && STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) - != VMAT_LOAD_STORE_LANES) + if (need_additional_vector_vars_p (stmt_info)) { /* For non-adjacent load/store STMT, we will potentially convert it into: @@ -752,7 +759,7 @@ update_local_live_ranges ( We will be likely using one more vector variable. */ unsigned int max_point - = (*program_points_per_bb.get (bb)).length () - 1; + = (*program_points_per_bb.get (bb)).length (); auto *live_ranges = live_ranges_per_bb.get (bb); bool existed_p = false; tree var = type == load_vec_info_type diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr114506.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr114506.c new file mode 100644 index 000..a88d24b2d2d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr114506.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize -mrvv-max-lmul=dynamic -fdump-tree-vect-details" } */ + +float a[32000], b[32000], c[32000], d[32000]; +float aa[256][256], bb[256][256], cc[256][256]; + +void +s2275 () +{ + for (int i = 0; i < 256; i++) +{ + for (int j = 0; j < 256; j++) + { + aa[j][i] = aa[j][i] + bb[j][i] * cc[j][i]; + } + a[i] = b[i] + c[i] * d[i]; +} +} + +/* { dg-final { scan-assembler-times {e32,m8} 1 } } */ +/* { dg-final { scan-assembler-not {e32,m4} } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "Preferring smaller LMUL loop because it has unexpected spills" "vect" } } */ -- 2.44.0
[PATCH v2] RISC-V: Refine the condition for add additional vars in RVV cost model
The adjacent_dr_p is sufficient and unnecessary condition for contiguous access. So unnecessary live-ranges are added and result in smaller LMUL. This patch uses MEMORY_ACCESS_TYPE as condition and constrains segment load/store. Tested on RV64 and no regression. PR target/114506 gcc/ChangeLog: * config/riscv/riscv-vector-costs.cc (non_contiguous_memory_access_p): Rename (need_additional_vector_vars_p): Rename and refine condition gcc/testsuite/ChangeLog: * gcc.dg/vect/costmodel/riscv/rvv/pr114506.c: New test. Signed-off-by: demin.han --- V2 changes: 1. remove max_point issue 2. minor change in commit message gcc/config/riscv/riscv-vector-costs.cc| 23 --- .../vect/costmodel/riscv/rvv/pr114506.c | 23 +++ 2 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr114506.c diff --git a/gcc/config/riscv/riscv-vector-costs.cc b/gcc/config/riscv/riscv-vector-costs.cc index f462c272a6e..484196b15b4 100644 --- a/gcc/config/riscv/riscv-vector-costs.cc +++ b/gcc/config/riscv/riscv-vector-costs.cc @@ -563,14 +563,24 @@ get_store_value (gimple *stmt) return gimple_assign_rhs1 (stmt); } -/* Return true if it is non-contiguous load/store. */ +/* Return true if addtional vector vars needed. */ static bool -non_contiguous_memory_access_p (stmt_vec_info stmt_info) +need_additional_vector_vars_p (stmt_vec_info stmt_info) { enum stmt_vec_info_type type = STMT_VINFO_TYPE (vect_stmt_to_vectorize (stmt_info)); - return ((type == load_vec_info_type || type == store_vec_info_type) - && !adjacent_dr_p (STMT_VINFO_DATA_REF (stmt_info))); + if (type == load_vec_info_type || type == store_vec_info_type) +{ + if (STMT_VINFO_GATHER_SCATTER_P (stmt_info) + && STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) == VMAT_GATHER_SCATTER) + return true; + + machine_mode mode = TYPE_MODE (STMT_VINFO_VECTYPE (stmt_info)); + int lmul = riscv_get_v_regno_alignment (mode); + if (DR_GROUP_SIZE (stmt_info) * lmul > RVV_M8) + return true; +} + return false; } /* Return the LMUL of the current analysis. */ @@ -739,10 +749,7 @@ update_local_live_ranges ( stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (si)); enum stmt_vec_info_type type = STMT_VINFO_TYPE (vect_stmt_to_vectorize (stmt_info)); - if (non_contiguous_memory_access_p (stmt_info) - /* LOAD_LANES/STORE_LANES doesn't need a perm indice. */ - && STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) - != VMAT_LOAD_STORE_LANES) + if (need_additional_vector_vars_p (stmt_info)) { /* For non-adjacent load/store STMT, we will potentially convert it into: diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr114506.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr114506.c new file mode 100644 index 000..a88d24b2d2d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr114506.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -ftree-vectorize -mrvv-max-lmul=dynamic -fdump-tree-vect-details" } */ + +float a[32000], b[32000], c[32000], d[32000]; +float aa[256][256], bb[256][256], cc[256][256]; + +void +s2275 () +{ + for (int i = 0; i < 256; i++) +{ + for (int j = 0; j < 256; j++) + { + aa[j][i] = aa[j][i] + bb[j][i] * cc[j][i]; + } + a[i] = b[i] + c[i] * d[i]; +} +} + +/* { dg-final { scan-assembler-times {e32,m8} 1 } } */ +/* { dg-final { scan-assembler-not {e32,m4} } } */ +/* { dg-final { scan-assembler-not {csrr} } } */ +/* { dg-final { scan-tree-dump-not "Preferring smaller LMUL loop because it has unexpected spills" "vect" } } */ -- 2.44.0
[PATCH] RISC-V: Minor fix for max_point
The program points start from 1, so max_point should be equal to length(). Tested on RV64 and no regression. gcc/ChangeLog: * config/riscv/riscv-vector-costs.cc: Use length() Signed-off-by: demin.han --- gcc/config/riscv/riscv-vector-costs.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/config/riscv/riscv-vector-costs.cc b/gcc/config/riscv/riscv-vector-costs.cc index 484196b15b4..9f7fe936a29 100644 --- a/gcc/config/riscv/riscv-vector-costs.cc +++ b/gcc/config/riscv/riscv-vector-costs.cc @@ -759,7 +759,7 @@ update_local_live_ranges ( We will be likely using one more vector variable. */ unsigned int max_point - = (*program_points_per_bb.get (bb)).length () - 1; + = (*program_points_per_bb.get (bb)).length (); auto *live_ranges = live_ranges_per_bb.get (bb); bool existed_p = false; tree var = type == load_vec_info_type -- 2.44.0
[PATCH] RISC-V: More support of vx and vf for autovec comparison
There are still some cases which can't utilize vx or vf for autovec comparison after last_combine pass. 1. integer comparison when imm isn't in range of [-16, 15] 2. float imm is 0.0 3. DI or DF mode under RV32 This patch fix above mentioned issues. Tested on RV32 and RV64. gcc/ChangeLog: * config/riscv/autovec.md: register_operand to nonmemory_operand * config/riscv/riscv-v.cc (get_cmp_insn_code): Select code according * to scalar_p (expand_vec_cmp): Generate scalar_p and transform op1 * config/riscv/riscv.cc (riscv_const_insns): Add !FLOAT_MODE_P * constrain * config/riscv/vector.md: Add !FLOAT_MODE_P constrain gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c: Fix test * gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv-nofm.c: Ditto * gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv-nofm.c: Ditto * gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c: Ditto * gcc.target/riscv/rvv/autovec/cmp/vcond-1.c: Fix and add test * gcc.target/riscv/rvv/autovec/cond/cond_copysign-rv32gcv.c: Fix * gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c: Fix test * gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmul-5.c: Ditto Signed-off-by: demin.han --- gcc/config/riscv/autovec.md | 2 +- gcc/config/riscv/riscv-v.cc | 72 --- gcc/config/riscv/riscv.cc | 2 +- gcc/config/riscv/vector.md| 3 +- .../rvv/autovec/binop/vadd-rv32gcv-nofm.c | 4 +- .../rvv/autovec/binop/vdiv-rv32gcv-nofm.c | 4 +- .../rvv/autovec/binop/vmul-rv32gcv-nofm.c | 4 +- .../rvv/autovec/binop/vsub-rv32gcv-nofm.c | 4 +- .../riscv/rvv/autovec/cmp/vcond-1.c | 48 - .../rvv/autovec/cond/cond_copysign-rv32gcv.c | 8 +-- .../riscv/rvv/autovec/cond/cond_fadd-1.c | 4 +- .../riscv/rvv/autovec/cond/cond_fadd-2.c | 4 +- .../riscv/rvv/autovec/cond/cond_fadd-3.c | 4 +- .../riscv/rvv/autovec/cond/cond_fadd-4.c | 4 +- .../riscv/rvv/autovec/cond/cond_fma_fnma-1.c | 4 +- .../riscv/rvv/autovec/cond/cond_fma_fnma-3.c | 4 +- .../riscv/rvv/autovec/cond/cond_fma_fnma-4.c | 4 +- .../riscv/rvv/autovec/cond/cond_fma_fnma-5.c | 4 +- .../riscv/rvv/autovec/cond/cond_fma_fnma-6.c | 4 +- .../riscv/rvv/autovec/cond/cond_fmax-1.c | 4 +- .../riscv/rvv/autovec/cond/cond_fmax-2.c | 4 +- .../riscv/rvv/autovec/cond/cond_fmax-3.c | 4 +- .../riscv/rvv/autovec/cond/cond_fmax-4.c | 4 +- .../riscv/rvv/autovec/cond/cond_fmin-1.c | 4 +- .../riscv/rvv/autovec/cond/cond_fmin-2.c | 4 +- .../riscv/rvv/autovec/cond/cond_fmin-3.c | 4 +- .../riscv/rvv/autovec/cond/cond_fmin-4.c | 4 +- .../riscv/rvv/autovec/cond/cond_fms_fnms-1.c | 4 +- .../riscv/rvv/autovec/cond/cond_fms_fnms-3.c | 4 +- .../riscv/rvv/autovec/cond/cond_fms_fnms-4.c | 4 +- .../riscv/rvv/autovec/cond/cond_fms_fnms-5.c | 4 +- .../riscv/rvv/autovec/cond/cond_fms_fnms-6.c | 4 +- .../riscv/rvv/autovec/cond/cond_fmul-1.c | 4 +- .../riscv/rvv/autovec/cond/cond_fmul-2.c | 4 +- .../riscv/rvv/autovec/cond/cond_fmul-3.c | 4 +- .../riscv/rvv/autovec/cond/cond_fmul-4.c | 4 +- .../riscv/r
[PATCH v2] RISC-V: More support of vx and vf for autovec comparison
There are still some cases which can't utilize vx or vf after last_combine pass. 1. integer comparison when imm isn't in range of [-16, 15] 2. float imm is 0.0 3. DI or DF mode under RV32 This patch fix above mentioned issues. Tested on RV32 and RV64. Signed-off-by: demin.han gcc/ChangeLog: * config/riscv/autovec.md: register_operand to nonmemory_operand * config/riscv/riscv-v.cc (get_cmp_insn_code): Select code according * to scalar_p (expand_vec_cmp): Generate scalar_p and transform op1 * config/riscv/riscv.cc (riscv_const_insns): Add !FLOAT_MODE_P * constrain gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/cmp/vcond-1.c: Fix and add test Signed-off-by: demin.han --- V2 changes: 1. remove unnecessary add_integer_operand and related code 2. fix one format issue 3. split patch and make it only related to vec cmp gcc/config/riscv/autovec.md | 2 +- gcc/config/riscv/riscv-v.cc | 57 +++ gcc/config/riscv/riscv.cc | 2 +- .../riscv/rvv/autovec/cmp/vcond-1.c | 48 +++- 4 files changed, 82 insertions(+), 27 deletions(-) diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index d5793acc999..a772153 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -690,7 +690,7 @@ (define_expand "vec_cmp" [(set (match_operand: 0 "register_operand") (match_operator: 1 "comparison_operator" [(match_operand:V_VLSF 2 "register_operand") - (match_operand:V_VLSF 3 "register_operand")]))] + (match_operand:V_VLSF 3 "nonmemory_operand")]))] "TARGET_VECTOR" { riscv_vector::expand_vec_cmp_float (operands[0], GET_CODE (operands[1]), diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index e290675bbf0..56328075aeb 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -2624,32 +2624,27 @@ expand_vec_init (rtx target, rtx vals) /* Get insn code for corresponding comparison. */ static insn_code -get_cmp_insn_code (rtx_code code, machine_mode mode) +get_cmp_insn_code (rtx_code code, machine_mode mode, bool scalar_p) { insn_code icode; - switch (code) + if (FLOAT_MODE_P (mode)) { -case EQ: -case NE: -case LE: -case LEU: -case GT: -case GTU: -case LTGT: - icode = code_for_pred_cmp (mode); - break; -case LT: -case LTU: -case GE: -case GEU: - if (FLOAT_MODE_P (mode)) - icode = code_for_pred_cmp (mode); + icode = !scalar_p ? code_for_pred_cmp (mode) + : code_for_pred_cmp_scalar (mode); + return icode; +} + if (scalar_p) +{ + if (code == GE || code == GEU) + icode = code_for_pred_ge_scalar (mode); else - icode = code_for_pred_ltge (mode); - break; -default: - gcc_unreachable (); + icode = code_for_pred_cmp_scalar (mode); + return icode; } + if (code == LT || code == LTU || code == GE || code == GEU) +icode = code_for_pred_ltge (mode); + else +icode = code_for_pred_cmp (mode); return icode; } @@ -2771,7 +2766,6 @@ expand_vec_cmp (rtx target, rtx_code code, rtx op0, rtx op1, rtx mask, { machine_mode mask_mode = GET_MODE (target); machine_mode data_mode = GET_MODE (op0); - insn_code icode = get_cmp_insn_code (code, data_mode); if (code == LTGT) { @@ -2779,12 +2773,29 @@ expand_vec_cmp (rtx target, rtx_code code, rtx op0, rtx op1, rtx mask, rtx gt = gen_reg_rtx (mask_mode); expand_vec_cmp (lt, LT, op0, op1, mask, maskoff); expand_vec_cmp (gt, GT, op0, op1, mask, maskoff); - icode = code_for_pred (IOR, mask_mode); + insn_code icode = code_for_pred (IOR, mask_mode); rtx ops[] = {target, lt, gt}; emit_vlmax_insn (icode, BINARY_MASK_OP, ops); return; } + rtx elt; + bool scalar_p = false; + if (const_vec_duplicate_p (op1, &elt)) +{ + if (FLOAT_MODE_P (data_mode)) + { + scalar_p = true; + op1 = force_reg (GET_MODE_INNER (GET_MODE (op1)), elt); + } + else if (!has_vi_variant_p (code, elt)) + { + scalar_p = true; + op1 = elt; + } +} + insn_code icode = get_cmp_insn_code (code, data_mode, scalar_p); + rtx cmp = gen_rtx_fmt_ee (code, mask_mode, op0, op1); if (!mask && !maskoff) { diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 19b9b2daa95..ad5668b2c5a 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2140,7 +2140,7 @@ riscv_const_insns (rtx x) register vec_duplicate into vmv.v.x. */ scalar_mode smode = GET_MODE_INNER (GET_MODE (x)); if (maybe_gt (GET_MODE_SIZE (smode), UNITS_PER_WORD) -
[PATCH] RISC-V: Fix double mode under RV32 not utilize vf
Currently, some binops of vector vs double scalar under RV32 can't translated to vf but vfmv+vxx.vv. The cause is that vec_duplicate is also expanded to broadcast for double mode under RV32. last-combine can't process expanded broadcast. gcc/ChangeLog: * config/riscv/vector.md: Add !FLOAT_MODE_P constrain gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c: Fix test * gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv-nofm.c: Ditto * gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv-nofm.c: Ditto * gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_copysign-rv32gcv.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c: Ditto * gcc.target/riscv/rvv/autovec/cond/cond_fmul-5.c: Ditto Signed-off-by: demin.han --- gcc/config/riscv/vector.md| 3 ++- .../riscv/rvv/autovec/binop/vadd-rv32gcv-nofm.c | 4 ++-- .../riscv/rvv/autovec/binop/vdiv-rv32gcv-nofm.c | 4 ++-- .../riscv/rvv/autovec/binop/vmul-rv32gcv-nofm.c | 4 ++-- .../riscv/rvv/autovec/binop/vsub-rv32gcv-nofm.c | 4 ++-- .../riscv/rvv/autovec/cond/cond_copysign-rv32gcv.c| 8 .../gcc.target/riscv/rvv/autovec/cond/cond_fadd-1.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fadd-2.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fadd-3.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fadd-4.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-1.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-3.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-4.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-5.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fma_fnma-6.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-1.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-3.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-4.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-5.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fms_fnms-6.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fmul-1.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fmul-2.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fmul-3.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fmul-4.c | 4 ++-- .../gcc.target/riscv/rvv/autovec/cond/cond_fmul-5.c | 4 ++-- 33 files changed, 68 insertions(+), 67 deletions(-) diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index bcedf3d79e2..d1518f3e623 100644 --- a/gcc/config/riscv/vector.md +++ b/
[PATCH v2] RISC-V: Remove float vector eqne pattern
We can unify eqne and other comparison operations. Tested on RV32 and RV64 gcc/ChangeLog: * config/riscv/riscv-vector-builtins-bases.cc: Remove eqne cond * config/riscv/vector.md (@pred_eqne_scalar): Remove patterns (*pred_eqne_scalar_merge_tie_mask): Ditto (*pred_eqne_scalar): Ditto (*pred_eqne_scalar_narrow): Ditto gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/float-point-cmp-eqne.c: New test. Signed-off-by: demin.han --- v2 changes: 1. add test Only intrinsics utilize those removed vf patterns. Auto vectorization use vv format now. The NaN will optimized out before expand in autovec as I tested. .../riscv/riscv-vector-builtins-bases.cc | 4 - gcc/config/riscv/vector.md| 86 --- .../riscv/rvv/base/float-point-cmp-eqne.c | 54 3 files changed, 54 insertions(+), 90 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/float-point-cmp-eqne.c diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index b6f6e4ff37e..d414721ede8 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -1420,10 +1420,6 @@ public: switch (e.op_info->op) { case OP_TYPE_vf: { - if (CODE == EQ || CODE == NE) - return e.use_compare_insn (CODE, code_for_pred_eqne_scalar ( - e.vector_mode ())); - else return e.use_compare_insn (CODE, code_for_pred_cmp_scalar ( e.vector_mode ())); } diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index fbcdf96f038..f8fae6557d9 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -7545,92 +7545,6 @@ (define_insn "*pred_cmp_scalar_narrow" (set_attr "mode" "") (set_attr "spec_restriction" "none,thv,thv,none,none")]) -(define_expand "@pred_eqne_scalar" - [(set (match_operand: 0 "register_operand") - (if_then_else: - (unspec: - [(match_operand: 1 "vector_mask_operand") -(match_operand 6 "vector_length_operand") -(match_operand 7 "const_int_operand") -(match_operand 8 "const_int_operand") -(reg:SI VL_REGNUM) -(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operator: 3 "equality_operator" -[(vec_duplicate:V_VLSF - (match_operand: 5 "register_operand")) - (match_operand:V_VLSF 4 "register_operand")]) - (match_operand: 2 "vector_merge_operand")))] - "TARGET_VECTOR" - {}) - -(define_insn "*pred_eqne_scalar_merge_tie_mask" - [(set (match_operand: 0 "register_operand" "=vm") - (if_then_else: - (unspec: - [(match_operand: 1 "register_operand" " 0") -(match_operand 5 "vector_length_operand" " rK") -(match_operand 6 "const_int_operand" " i") -(match_operand 7 "const_int_operand" " i") -(reg:SI VL_REGNUM) -(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operator: 2 "equality_operator" -[(vec_duplicate:V_VLSF - (match_operand: 4 "register_operand" " f")) - (match_operand:V_VLSF 3 "register_operand" " vr")]) - (match_dup 1)))] - "TARGET_VECTOR" - "vmf%B2.vf\t%0,%3,%4,v0.t" - [(set_attr "type" "vfcmp") - (set_attr "mode" "") - (set_attr "merge_op_idx" "1") - (set_attr "vl_op_idx" "5") - (set (attr "ma") (symbol_ref "riscv_vector::get_ma(operands[6])")) - (set (attr "avl_type_idx") (const_int 7))]) - -;; We don't use early-clobber for LMUL <= 1 to get better codegen. -(define_insn "*pred_eqne_scalar" - [(set (match_operand: 0 "register_operand""=vr, vr, &vr, &vr") - (if_then_else: - (unspec: - [(match_operand: 1 "vector_mask_operand" "vmWc1,vmWc1,vmWc1,vmWc1") -(match_operand 6 "vector_length_operand" " rK, rK, rK, rK") -(match_operand 7 "const_int_operand" "i,i, i,i") -(match_operand 8 "const_int_operand" "i,i, i,i") -(reg:SI VL_REGNUM) -
[PATCH v2] RISC-V: Remove integer vector eqne pattern
We can unify eqne and other comparison operations. Tested on RV32 and RV64. gcc/ChangeLog: * config/riscv/predicates.md (comparison_except_eqge_operator): Only exclude ge (comparison_except_ge_operator): Ditto * config/riscv/riscv-string.cc (expand_rawmemchr): Use cmp pattern (expand_strcmp): Ditto * config/riscv/riscv-vector-builtins-bases.cc: Remove eqne cond * config/riscv/vector.md (@pred_eqne_scalar): Remove eqne patterns (*pred_eqne_scalar_merge_tie_mask): Ditto (*pred_eqne_scalar): Ditto (*pred_eqne_scalar_narrow): Ditto (*pred_eqne_extended_scalar_merge_tie_mask): Ditto (*pred_eqne_extended_scalar): Ditto (*pred_eqne_extended_scalar_narrow): Ditto gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/integer-cmp-eqne.c: New test. Signed-off-by: demin.han --- v2 changes: 1. add test gcc/config/riscv/predicates.md| 4 +- gcc/config/riscv/riscv-string.cc | 4 +- .../riscv/riscv-vector-builtins-bases.cc | 3 - gcc/config/riscv/vector.md| 279 +- .../riscv/rvv/base/integer-cmp-eqne.c | 66 + 5 files changed, 81 insertions(+), 275 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/integer-cmp-eqne.c diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 0fb5729fdcf..9971fabc587 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -568,8 +568,8 @@ (define_predicate "ltge_operator" (define_predicate "comparison_except_ltge_operator" (match_code "eq,ne,le,leu,gt,gtu")) -(define_predicate "comparison_except_eqge_operator" - (match_code "le,leu,gt,gtu,lt,ltu")) +(define_predicate "comparison_except_ge_operator" + (match_code "eq,ne,le,leu,gt,gtu,lt,ltu")) (define_predicate "ge_operator" (match_code "ge,geu")) diff --git a/gcc/config/riscv/riscv-string.cc b/gcc/config/riscv/riscv-string.cc index 83e7afbd693..4702001bd9b 100644 --- a/gcc/config/riscv/riscv-string.cc +++ b/gcc/config/riscv/riscv-string.cc @@ -1342,7 +1342,7 @@ expand_rawmemchr (machine_mode mode, rtx dst, rtx haystack, rtx needle, /* Compare needle with haystack and store in a mask. */ rtx eq = gen_rtx_EQ (mask_mode, gen_const_vec_duplicate (vmode, needle), vec); rtx vmsops[] = {mask, eq, vec, needle}; - emit_nonvlmax_insn (code_for_pred_eqne_scalar (vmode), + emit_nonvlmax_insn (code_for_pred_cmp_scalar (vmode), riscv_vector::COMPARE_OP, vmsops, cnt); /* Find the first bit in the mask. */ @@ -1468,7 +1468,7 @@ expand_strcmp (rtx result, rtx src1, rtx src2, rtx nbytes, = gen_rtx_EQ (mask_mode, gen_const_vec_duplicate (vmode, CONST0_RTX (mode)), vec1); rtx vmsops1[] = {mask0, eq0, vec1, CONST0_RTX (mode)}; - emit_nonvlmax_insn (code_for_pred_eqne_scalar (vmode), + emit_nonvlmax_insn (code_for_pred_cmp_scalar (vmode), riscv_vector::COMPARE_OP, vmsops1, cnt); /* Look for vec1 != vec2 (includes vec2[i] == 0). */ diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc index 596b88cc8a3..6483faba39c 100644 --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc @@ -718,9 +718,6 @@ public: if (CODE == GE || CODE == GEU) return e.use_compare_insn (CODE, code_for_pred_ge_scalar ( e.vector_mode ())); - else if (CODE == EQ || CODE == NE) - return e.use_compare_insn (CODE, code_for_pred_eqne_scalar ( - e.vector_mode ())); else return e.use_compare_insn (CODE, code_for_pred_cmp_scalar ( e.vector_mode ())); diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index f8fae6557d9..fe18ee5b5f7 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -4704,7 +4704,7 @@ (define_expand "@pred_cmp_scalar" (match_operand 8 "const_int_operand") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operator: 3 "comparison_except_eqge_operator" + (match_operator: 3 "comparison_except_ge_operator" [(match_operand:V_VLSI_QHS 4 "register_operand") (vec_duplicate:V_VLSI_QHS (match_operand: 5 "register_operand"))]) @@ -4722,7 +4722,7 @@ (define_insn "*pred_cmp_scalar_merge_tie_mask" (match_operand 7 "const_int_operand" " i") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) -