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 <demin....@starfivetech.com> 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 <demin....@starfivetech.com> --- 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..a7111172153 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -690,7 +690,7 @@ (define_expand "vec_cmp<mode><vm>" [(set (match_operand:<VM> 0 "register_operand") (match_operator:<VM> 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) - && !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 0faedacb2c7..6a072aab281 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) \ + T (float, float, COND, IMM, SUFFIX##_float_float) \ + T (double, double, COND, IMM, SUFFIX##_double_double) + +#define TEST_IMM_FLOAT_ALL(T) \ + TEST_COND_IMM_FLOAT (T, >, 0.0, _gt) \ + TEST_COND_IMM_FLOAT (T, <, 0.0, _lt) \ + TEST_COND_IMM_FLOAT (T, >=, 0.0, _ge) \ + TEST_COND_IMM_FLOAT (T, <=, 0.0, _le) \ + TEST_COND_IMM_FLOAT (T, ==, 0.0, _eq) \ + TEST_COND_IMM_FLOAT (T, !=, 0.0, _ne) \ + \ + TEST_COND_IMM_FLOAT (T, >, 1.0, _gt1) \ + TEST_COND_IMM_FLOAT (T, <, 1.0, _lt1) \ + TEST_COND_IMM_FLOAT (T, >=, 1.0, _ge1) \ + TEST_COND_IMM_FLOAT (T, <=, 1.0, _le1) \ + TEST_COND_IMM_FLOAT (T, ==, 1.0, _eq1) \ + TEST_COND_IMM_FLOAT (T, !=, 1.0, _ne1) \ + \ + TEST_COND_IMM_FLOAT (T, >, -1.0, _gt2) \ + TEST_COND_IMM_FLOAT (T, <, -1.0, _lt2) \ + TEST_COND_IMM_FLOAT (T, >=, -1.0, _ge2) \ + TEST_COND_IMM_FLOAT (T, <=, -1.0, _le2) \ + TEST_COND_IMM_FLOAT (T, ==, -1.0, _eq2) \ + TEST_COND_IMM_FLOAT (T, !=, -1.0, _ne2) + +TEST_IMM_FLOAT_ALL (DEF_VCOND_IMM) + /* { dg-final { scan-assembler-times {\tvmseq\.vi} 42 } } */ /* { dg-final { scan-assembler-times {\tvmsne\.vi} 42 } } */ /* { dg-final { scan-assembler-times {\tvmsgt\.vi} 30 } } */ @@ -152,6 +180,22 @@ TEST_IMM_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} 56 } } */ +/* { dg-final { scan-assembler-times {\tvmsge} 20 } } */ /* { dg-final { scan-assembler-times {\tvmsle} 82 } } */ +/* { dg-final { scan-assembler-times {\tvmseq\.vx} 24 } } */ +/* { dg-final { scan-assembler-times {\tvmsne\.vx} 24 } } */ +/* { dg-final { scan-assembler-times {\tvmsgt\.vx} 6 } } */ +/* { dg-final { scan-assembler-times {\tvmsgtu\.vx} 22 } } */ +/* { dg-final { scan-assembler-times {\tvmslt\.vx} 36 } } */ +/* { 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} 6 } } */ +/* { dg-final { scan-assembler-times {\tvmsleu\.vx} 22 } } */ +/* { dg-final { scan-assembler-times {\tvmfgt.vf} 6 } } */ +/* { dg-final { scan-assembler-times {\tvmflt.vf} 6 } } */ +/* { dg-final { scan-assembler-times {\tvmfge.vf} 6 } } */ +/* { dg-final { scan-assembler-times {\tvmfle.vf} 6 } } */ +/* { dg-final { scan-assembler-times {\tvmfeq.vf} 6 } } */ +/* { dg-final { scan-assembler-times {\tvmfne.vf} 6 } } */ -- 2.45.2