> +  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)                                     
> \

Just curious, does this patch covered float imm is -0.0 (notice only +0.0 is 
mentioned)?
If so we can have similar tests as +0.0 here.

It is totally Ok if -0.0f is not applicable here.

Pan

-----Original Message-----
From: demin.han <demin....@starfivetech.com> 
Sent: Friday, July 19, 2024 4:55 PM
To: gcc-patches@gcc.gnu.org
Cc: juzhe.zh...@rivai.ai; kito.ch...@gmail.com; Li, Pan2 <pan2...@intel.com>; 
jeffreya...@gmail.com; rdapp....@gmail.com
Subject: [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 <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

Reply via email to