public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v1] RISC-V: Refine the code gen for ceil auto vectorization.
@ 2023-09-22 11:19 pan2.li
  2023-09-22 11:25 ` juzhe.zhong
  2023-09-22 12:16 ` [PATCH v2] " pan2.li
  0 siblings, 2 replies; 6+ messages in thread
From: pan2.li @ 2023-09-22 11:19 UTC (permalink / raw)
  To: gcc-patches; +Cc: juzhe.zhong, pan2.li, yanzhang.wang, kito.cheng

From: Pan Li <pan2.li@intel.com>

We vectorized below ceil code already.

void
test_ceil (float *out, float *in, int count)
{
  for (unsigned i = 0; i < count; i++)
    out[i] = __builtin_ceilf (in[i]);
}

Before this patch:
vfmv.v.x    v4,fa0     // can be removed
vfabs.v     v0,v1
vmv1r.v     v2,v1      // can be removed
vmflt.vv    v0,v0,v4   // can be refined to vmflt.vf
vfcvt.x.f.v v3,v1,v0.t
vfcvt.f.x.v v2,v3,v0.t
vfsgnj.vv   v2,v2,v1

After this patch:
vfabs.v     v1,v2
vmflt.vf    v0,v1,fa5
vfcvt.x.f.v v3,v2,v0.t
vfcvt.f.x.v v1,v3,v0.t
vfsgnj.vv   v1,v1,v2

We can generate better code include below items.

* Remove vfmv.v.f.
* Take vmflt.vf instead of vmflt.vv.
* Remove vmv1r.v.

gcc/ChangeLog:

	* config/riscv/riscv-v.cc (expand_vec_float_cmp_mask): Refactor.
	(expand_vec_abs): New function impl.
	(expand_vec_cvt_x_f): Ditto.
	(expand_vec_cvt_f_x): Ditto.
	(expand_vec_ceil): Refine.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c: Adjust body check.
	* gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c: Ditto.
	* gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c: Ditto.
	* gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c: Ditto.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/config/riscv/riscv-v.cc                   | 71 ++++++++++++-------
 .../riscv/rvv/autovec/unop/math-ceil-0.c      |  5 +-
 .../riscv/rvv/autovec/unop/math-ceil-1.c      |  5 +-
 .../riscv/rvv/autovec/unop/math-ceil-2.c      |  5 +-
 .../riscv/rvv/autovec/unop/math-ceil-3.c      |  5 +-
 5 files changed, 49 insertions(+), 42 deletions(-)

diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 4d0e1d8d1a9..ea2b01f6a6e 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -3560,26 +3560,17 @@ static rtx
 expand_vec_float_cmp_mask (rtx fp_vector, rtx_code code, rtx fp_scalar,
 			   machine_mode vec_fp_mode)
 {
-  /* Step-1: Get the abs float value for mask generation.  */
-  rtx tmp = gen_reg_rtx (vec_fp_mode);
-  rtx abs_ops[] = {tmp, fp_vector};
-  insn_code icode = code_for_pred (ABS, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP, abs_ops);
-
-  /* Step-2: Prepare the scalar float compare register.  */
+  /* Step-1: Prepare the scalar float compare register.  */
   rtx fp_reg = gen_reg_rtx (GET_MODE_INNER (vec_fp_mode));
   emit_insn (gen_move_insn (fp_reg, fp_scalar));
 
-  /* Step-3: Prepare the vector float compare register.  */
-  rtx vec_dup = gen_reg_rtx (vec_fp_mode);
-  icode = code_for_pred_broadcast (vec_fp_mode);
-  rtx vfmv_ops[] = {vec_dup, fp_reg};
-  emit_vlmax_insn (icode, UNARY_OP, vfmv_ops);
-
-  /* Step-4: Generate the mask.  */
+  /* Step-2: Generate the mask.  */
   machine_mode mask_mode = get_mask_mode (vec_fp_mode);
   rtx mask = gen_reg_rtx (mask_mode);
-  expand_vec_cmp (mask, code, tmp, vec_dup);
+  rtx cmp = gen_rtx_fmt_ee (code, mask_mode, fp_vector, fp_reg);
+  rtx cmp_ops[] = {mask, cmp, fp_vector, fp_reg};
+  insn_code icode = code_for_pred_cmp_scalar (vec_fp_mode);
+  emit_vlmax_insn (icode, COMPARE_OP, cmp_ops);
 
   return mask;
 }
@@ -3594,29 +3585,57 @@ expand_vec_copysign (rtx op_dest, rtx op_src_0, rtx op_src_1,
   emit_vlmax_insn (icode, BINARY_OP, sgnj_ops);
 }
 
+static void
+expand_vec_abs (rtx op_dest, rtx op_src, machine_mode vec_mode)
+{
+  rtx abs_ops[] = {op_dest, op_src};
+  insn_code icode = code_for_pred (ABS, vec_mode);
+
+  emit_vlmax_insn (icode, UNARY_OP, abs_ops);
+}
+
+static void
+expand_vec_cvt_x_f (rtx op_dest, rtx op_src, rtx mask,
+		    insn_type type, machine_mode vec_mode)
+{
+  rtx cvt_x_ops[] = {op_dest, mask, op_dest, op_src};
+  insn_code icode = code_for_pred_fcvt_x_f (UNSPEC_VFCVT, vec_mode);
+
+  emit_vlmax_insn (icode, type, cvt_x_ops);
+}
+
+static void
+expand_vec_cvt_f_x (rtx op_dest, rtx op_src, rtx mask,
+		    insn_type type, machine_mode vec_mode)
+{
+  rtx cvt_fp_ops[] = {op_dest, mask, op_dest, op_src};
+  insn_code icode = code_for_pred (FLOAT, vec_mode);
+
+  emit_vlmax_insn (icode, type, cvt_fp_ops);
+}
+
 void
 expand_vec_ceil (rtx op_0, rtx op_1, machine_mode vec_fp_mode,
 		 machine_mode vec_int_mode)
 {
-  /* Step-1: Generate the mask on const fp.  */
+  /* Step-1: Get the abs float value for mask generation.  */
+  expand_vec_abs (op_0, op_1, vec_fp_mode);
+
+  /* Step-2: Generate the mask on const fp.  */
   rtx const_fp = gen_ceil_const_fp (GET_MODE_INNER (vec_fp_mode));
-  rtx mask = expand_vec_float_cmp_mask (op_1, LT, const_fp, vec_fp_mode);
+  rtx mask = expand_vec_float_cmp_mask (op_0, LT, const_fp, vec_fp_mode);
 
-  /* Step-2: Convert to integer on mask, with rounding up (aka ceil).  */
+  /* Step-3: Convert to integer on mask, with rounding up (aka ceil).  */
   rtx tmp = gen_reg_rtx (vec_int_mode);
-  rtx cvt_x_ops[] = {tmp, mask, tmp, op_1};
-  insn_code icode = code_for_pred_fcvt_x_f (UNSPEC_VFCVT, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP_TAMU_FRM_RUP, cvt_x_ops);
+  expand_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMU_FRM_RUP, vec_fp_mode);
 
-  /* Step-3: Convert to floating-point on mask for the final result.
+  /* Step-4: Convert to floating-point on mask for the final result.
      To avoid unnecessary frm register access, we use RUP here and it will
      never do the rounding up because the tmp rtx comes from the float
      to int conversion.  */
-  rtx cvt_fp_ops[] = {op_0, mask, op_1, tmp};
-  icode = code_for_pred (FLOAT, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP_TAMU_FRM_RUP, cvt_fp_ops);
+  expand_vec_cvt_f_x (op_0, tmp, mask, UNARY_OP_TAMU_FRM_RUP, vec_fp_mode);
 
-  /* Step-4: Retrieve the sign bit.  */
+  /* Step-5: Retrieve the sign bit.  */
   expand_vec_copysign (op_0, op_0, op_1, vec_fp_mode);
 }
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
index 0959afd57d6..1c53d9b67d3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
@@ -12,11 +12,8 @@
 **   ...
 **   vsetvli\s+[atx][0-9]+,\s*zero,\s*e16,\s*m1,\s*ta,\s*mu
 **   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
 **   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
 **   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
 **   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
 **   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
index 142705b7eed..a6d0ac3fc83 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
@@ -12,11 +12,8 @@
 **   ...
 **   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
 **   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
 **   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
 **   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
 **   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
 **   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
index d232e36e1db..d196fc678c4 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
@@ -12,11 +12,8 @@
 **   ...
 **   vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*mu
 **   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
 **   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
 **   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
 **   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
 **   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
index 82e4f89a82a..cd3df49de6d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
@@ -12,11 +12,8 @@
 **   ...
 **   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
 **   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
 **   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
 **   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
 **   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
 **   ...
-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v1] RISC-V: Refine the code gen for ceil auto vectorization.
  2023-09-22 11:19 [PATCH v1] RISC-V: Refine the code gen for ceil auto vectorization pan2.li
@ 2023-09-22 11:25 ` juzhe.zhong
  2023-09-22 11:30   ` Li, Pan2
  2023-09-22 12:16 ` [PATCH v2] " pan2.li
  1 sibling, 1 reply; 6+ messages in thread
From: juzhe.zhong @ 2023-09-22 11:25 UTC (permalink / raw)
  To: pan2.li, gcc-patches; +Cc: pan2.li, yanzhang.wang, kito.cheng

[-- Attachment #1: Type: text/plain, Size: 9047 bytes --]

I prefer change expand_vec_copysign into emit_vec_copysign。

Likewise, emit_fabs. ...etc.



juzhe.zhong@rivai.ai
 
From: pan2.li
Date: 2023-09-22 19:19
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v1] RISC-V: Refine the code gen for ceil auto vectorization.
From: Pan Li <pan2.li@intel.com>
 
We vectorized below ceil code already.
 
void
test_ceil (float *out, float *in, int count)
{
  for (unsigned i = 0; i < count; i++)
    out[i] = __builtin_ceilf (in[i]);
}
 
Before this patch:
vfmv.v.x    v4,fa0     // can be removed
vfabs.v     v0,v1
vmv1r.v     v2,v1      // can be removed
vmflt.vv    v0,v0,v4   // can be refined to vmflt.vf
vfcvt.x.f.v v3,v1,v0.t
vfcvt.f.x.v v2,v3,v0.t
vfsgnj.vv   v2,v2,v1
 
After this patch:
vfabs.v     v1,v2
vmflt.vf    v0,v1,fa5
vfcvt.x.f.v v3,v2,v0.t
vfcvt.f.x.v v1,v3,v0.t
vfsgnj.vv   v1,v1,v2
 
We can generate better code include below items.
 
* Remove vfmv.v.f.
* Take vmflt.vf instead of vmflt.vv.
* Remove vmv1r.v.
 
gcc/ChangeLog:
 
* config/riscv/riscv-v.cc (expand_vec_float_cmp_mask): Refactor.
(expand_vec_abs): New function impl.
(expand_vec_cvt_x_f): Ditto.
(expand_vec_cvt_f_x): Ditto.
(expand_vec_ceil): Refine.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c: Adjust body check.
* gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c: Ditto.
 
Signed-off-by: Pan Li <pan2.li@intel.com>
---
gcc/config/riscv/riscv-v.cc                   | 71 ++++++++++++-------
.../riscv/rvv/autovec/unop/math-ceil-0.c      |  5 +-
.../riscv/rvv/autovec/unop/math-ceil-1.c      |  5 +-
.../riscv/rvv/autovec/unop/math-ceil-2.c      |  5 +-
.../riscv/rvv/autovec/unop/math-ceil-3.c      |  5 +-
5 files changed, 49 insertions(+), 42 deletions(-)
 
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 4d0e1d8d1a9..ea2b01f6a6e 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -3560,26 +3560,17 @@ static rtx
expand_vec_float_cmp_mask (rtx fp_vector, rtx_code code, rtx fp_scalar,
   machine_mode vec_fp_mode)
{
-  /* Step-1: Get the abs float value for mask generation.  */
-  rtx tmp = gen_reg_rtx (vec_fp_mode);
-  rtx abs_ops[] = {tmp, fp_vector};
-  insn_code icode = code_for_pred (ABS, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP, abs_ops);
-
-  /* Step-2: Prepare the scalar float compare register.  */
+  /* Step-1: Prepare the scalar float compare register.  */
   rtx fp_reg = gen_reg_rtx (GET_MODE_INNER (vec_fp_mode));
   emit_insn (gen_move_insn (fp_reg, fp_scalar));
-  /* Step-3: Prepare the vector float compare register.  */
-  rtx vec_dup = gen_reg_rtx (vec_fp_mode);
-  icode = code_for_pred_broadcast (vec_fp_mode);
-  rtx vfmv_ops[] = {vec_dup, fp_reg};
-  emit_vlmax_insn (icode, UNARY_OP, vfmv_ops);
-
-  /* Step-4: Generate the mask.  */
+  /* Step-2: Generate the mask.  */
   machine_mode mask_mode = get_mask_mode (vec_fp_mode);
   rtx mask = gen_reg_rtx (mask_mode);
-  expand_vec_cmp (mask, code, tmp, vec_dup);
+  rtx cmp = gen_rtx_fmt_ee (code, mask_mode, fp_vector, fp_reg);
+  rtx cmp_ops[] = {mask, cmp, fp_vector, fp_reg};
+  insn_code icode = code_for_pred_cmp_scalar (vec_fp_mode);
+  emit_vlmax_insn (icode, COMPARE_OP, cmp_ops);
   return mask;
}
@@ -3594,29 +3585,57 @@ expand_vec_copysign (rtx op_dest, rtx op_src_0, rtx op_src_1,
   emit_vlmax_insn (icode, BINARY_OP, sgnj_ops);
}
+static void
+expand_vec_abs (rtx op_dest, rtx op_src, machine_mode vec_mode)
+{
+  rtx abs_ops[] = {op_dest, op_src};
+  insn_code icode = code_for_pred (ABS, vec_mode);
+
+  emit_vlmax_insn (icode, UNARY_OP, abs_ops);
+}
+
+static void
+expand_vec_cvt_x_f (rtx op_dest, rtx op_src, rtx mask,
+     insn_type type, machine_mode vec_mode)
+{
+  rtx cvt_x_ops[] = {op_dest, mask, op_dest, op_src};
+  insn_code icode = code_for_pred_fcvt_x_f (UNSPEC_VFCVT, vec_mode);
+
+  emit_vlmax_insn (icode, type, cvt_x_ops);
+}
+
+static void
+expand_vec_cvt_f_x (rtx op_dest, rtx op_src, rtx mask,
+     insn_type type, machine_mode vec_mode)
+{
+  rtx cvt_fp_ops[] = {op_dest, mask, op_dest, op_src};
+  insn_code icode = code_for_pred (FLOAT, vec_mode);
+
+  emit_vlmax_insn (icode, type, cvt_fp_ops);
+}
+
void
expand_vec_ceil (rtx op_0, rtx op_1, machine_mode vec_fp_mode,
machine_mode vec_int_mode)
{
-  /* Step-1: Generate the mask on const fp.  */
+  /* Step-1: Get the abs float value for mask generation.  */
+  expand_vec_abs (op_0, op_1, vec_fp_mode);
+
+  /* Step-2: Generate the mask on const fp.  */
   rtx const_fp = gen_ceil_const_fp (GET_MODE_INNER (vec_fp_mode));
-  rtx mask = expand_vec_float_cmp_mask (op_1, LT, const_fp, vec_fp_mode);
+  rtx mask = expand_vec_float_cmp_mask (op_0, LT, const_fp, vec_fp_mode);
-  /* Step-2: Convert to integer on mask, with rounding up (aka ceil).  */
+  /* Step-3: Convert to integer on mask, with rounding up (aka ceil).  */
   rtx tmp = gen_reg_rtx (vec_int_mode);
-  rtx cvt_x_ops[] = {tmp, mask, tmp, op_1};
-  insn_code icode = code_for_pred_fcvt_x_f (UNSPEC_VFCVT, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP_TAMU_FRM_RUP, cvt_x_ops);
+  expand_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMU_FRM_RUP, vec_fp_mode);
-  /* Step-3: Convert to floating-point on mask for the final result.
+  /* Step-4: Convert to floating-point on mask for the final result.
      To avoid unnecessary frm register access, we use RUP here and it will
      never do the rounding up because the tmp rtx comes from the float
      to int conversion.  */
-  rtx cvt_fp_ops[] = {op_0, mask, op_1, tmp};
-  icode = code_for_pred (FLOAT, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP_TAMU_FRM_RUP, cvt_fp_ops);
+  expand_vec_cvt_f_x (op_0, tmp, mask, UNARY_OP_TAMU_FRM_RUP, vec_fp_mode);
-  /* Step-4: Retrieve the sign bit.  */
+  /* Step-5: Retrieve the sign bit.  */
   expand_vec_copysign (op_0, op_0, op_1, vec_fp_mode);
}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
index 0959afd57d6..1c53d9b67d3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e16,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
index 142705b7eed..a6d0ac3fc83 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
index d232e36e1db..d196fc678c4 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
index 82e4f89a82a..cd3df49de6d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
-- 
2.34.1
 
 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [PATCH v1] RISC-V: Refine the code gen for ceil auto vectorization.
  2023-09-22 11:25 ` juzhe.zhong
@ 2023-09-22 11:30   ` Li, Pan2
  0 siblings, 0 replies; 6+ messages in thread
From: Li, Pan2 @ 2023-09-22 11:30 UTC (permalink / raw)
  To: juzhe.zhong, gcc-patches; +Cc: Wang, Yanzhang, kito.cheng

[-- Attachment #1: Type: text/plain, Size: 9734 bytes --]

Sure thing, will send V2 for this.

Pan

From: juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai>
Sent: Friday, September 22, 2023 7:26 PM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Li, Pan2 <pan2.li@intel.com>; Wang, Yanzhang <yanzhang.wang@intel.com>; kito.cheng <kito.cheng@gmail.com>
Subject: Re: [PATCH v1] RISC-V: Refine the code gen for ceil auto vectorization.

I prefer change expand_vec_copysign into emit_vec_copysign。

Likewise, emit_fabs. ...etc.

________________________________
juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>

From: pan2.li<mailto:pan2.li@intel.com>
Date: 2023-09-22 19:19
To: gcc-patches<mailto:gcc-patches@gcc.gnu.org>
CC: juzhe.zhong<mailto:juzhe.zhong@rivai.ai>; pan2.li<mailto:pan2.li@intel.com>; yanzhang.wang<mailto:yanzhang.wang@intel.com>; kito.cheng<mailto:kito.cheng@gmail.com>
Subject: [PATCH v1] RISC-V: Refine the code gen for ceil auto vectorization.
From: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>

We vectorized below ceil code already.

void
test_ceil (float *out, float *in, int count)
{
  for (unsigned i = 0; i < count; i++)
    out[i] = __builtin_ceilf (in[i]);
}

Before this patch:
vfmv.v.x    v4,fa0     // can be removed
vfabs.v     v0,v1
vmv1r.v     v2,v1      // can be removed
vmflt.vv    v0,v0,v4   // can be refined to vmflt.vf
vfcvt.x.f.v v3,v1,v0.t
vfcvt.f.x.v v2,v3,v0.t
vfsgnj.vv   v2,v2,v1

After this patch:
vfabs.v     v1,v2
vmflt.vf    v0,v1,fa5
vfcvt.x.f.v v3,v2,v0.t
vfcvt.f.x.v v1,v3,v0.t
vfsgnj.vv   v1,v1,v2

We can generate better code include below items.

* Remove vfmv.v.f.
* Take vmflt.vf instead of vmflt.vv.
* Remove vmv1r.v.

gcc/ChangeLog:

* config/riscv/riscv-v.cc (expand_vec_float_cmp_mask): Refactor.
(expand_vec_abs): New function impl.
(expand_vec_cvt_x_f): Ditto.
(expand_vec_cvt_f_x): Ditto.
(expand_vec_ceil): Refine.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c: Adjust body check.
* gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c: Ditto.

Signed-off-by: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>
---
gcc/config/riscv/riscv-v.cc                   | 71 ++++++++++++-------
.../riscv/rvv/autovec/unop/math-ceil-0.c      |  5 +-
.../riscv/rvv/autovec/unop/math-ceil-1.c      |  5 +-
.../riscv/rvv/autovec/unop/math-ceil-2.c      |  5 +-
.../riscv/rvv/autovec/unop/math-ceil-3.c      |  5 +-
5 files changed, 49 insertions(+), 42 deletions(-)

diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 4d0e1d8d1a9..ea2b01f6a6e 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -3560,26 +3560,17 @@ static rtx
expand_vec_float_cmp_mask (rtx fp_vector, rtx_code code, rtx fp_scalar,
   machine_mode vec_fp_mode)
{
-  /* Step-1: Get the abs float value for mask generation.  */
-  rtx tmp = gen_reg_rtx (vec_fp_mode);
-  rtx abs_ops[] = {tmp, fp_vector};
-  insn_code icode = code_for_pred (ABS, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP, abs_ops);
-
-  /* Step-2: Prepare the scalar float compare register.  */
+  /* Step-1: Prepare the scalar float compare register.  */
   rtx fp_reg = gen_reg_rtx (GET_MODE_INNER (vec_fp_mode));
   emit_insn (gen_move_insn (fp_reg, fp_scalar));
-  /* Step-3: Prepare the vector float compare register.  */
-  rtx vec_dup = gen_reg_rtx (vec_fp_mode);
-  icode = code_for_pred_broadcast (vec_fp_mode);
-  rtx vfmv_ops[] = {vec_dup, fp_reg};
-  emit_vlmax_insn (icode, UNARY_OP, vfmv_ops);
-
-  /* Step-4: Generate the mask.  */
+  /* Step-2: Generate the mask.  */
   machine_mode mask_mode = get_mask_mode (vec_fp_mode);
   rtx mask = gen_reg_rtx (mask_mode);
-  expand_vec_cmp (mask, code, tmp, vec_dup);
+  rtx cmp = gen_rtx_fmt_ee (code, mask_mode, fp_vector, fp_reg);
+  rtx cmp_ops[] = {mask, cmp, fp_vector, fp_reg};
+  insn_code icode = code_for_pred_cmp_scalar (vec_fp_mode);
+  emit_vlmax_insn (icode, COMPARE_OP, cmp_ops);
   return mask;
}
@@ -3594,29 +3585,57 @@ expand_vec_copysign (rtx op_dest, rtx op_src_0, rtx op_src_1,
   emit_vlmax_insn (icode, BINARY_OP, sgnj_ops);
}
+static void
+expand_vec_abs (rtx op_dest, rtx op_src, machine_mode vec_mode)
+{
+  rtx abs_ops[] = {op_dest, op_src};
+  insn_code icode = code_for_pred (ABS, vec_mode);
+
+  emit_vlmax_insn (icode, UNARY_OP, abs_ops);
+}
+
+static void
+expand_vec_cvt_x_f (rtx op_dest, rtx op_src, rtx mask,
+     insn_type type, machine_mode vec_mode)
+{
+  rtx cvt_x_ops[] = {op_dest, mask, op_dest, op_src};
+  insn_code icode = code_for_pred_fcvt_x_f (UNSPEC_VFCVT, vec_mode);
+
+  emit_vlmax_insn (icode, type, cvt_x_ops);
+}
+
+static void
+expand_vec_cvt_f_x (rtx op_dest, rtx op_src, rtx mask,
+     insn_type type, machine_mode vec_mode)
+{
+  rtx cvt_fp_ops[] = {op_dest, mask, op_dest, op_src};
+  insn_code icode = code_for_pred (FLOAT, vec_mode);
+
+  emit_vlmax_insn (icode, type, cvt_fp_ops);
+}
+
void
expand_vec_ceil (rtx op_0, rtx op_1, machine_mode vec_fp_mode,
machine_mode vec_int_mode)
{
-  /* Step-1: Generate the mask on const fp.  */
+  /* Step-1: Get the abs float value for mask generation.  */
+  expand_vec_abs (op_0, op_1, vec_fp_mode);
+
+  /* Step-2: Generate the mask on const fp.  */
   rtx const_fp = gen_ceil_const_fp (GET_MODE_INNER (vec_fp_mode));
-  rtx mask = expand_vec_float_cmp_mask (op_1, LT, const_fp, vec_fp_mode);
+  rtx mask = expand_vec_float_cmp_mask (op_0, LT, const_fp, vec_fp_mode);
-  /* Step-2: Convert to integer on mask, with rounding up (aka ceil).  */
+  /* Step-3: Convert to integer on mask, with rounding up (aka ceil).  */
   rtx tmp = gen_reg_rtx (vec_int_mode);
-  rtx cvt_x_ops[] = {tmp, mask, tmp, op_1};
-  insn_code icode = code_for_pred_fcvt_x_f (UNSPEC_VFCVT, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP_TAMU_FRM_RUP, cvt_x_ops);
+  expand_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMU_FRM_RUP, vec_fp_mode);
-  /* Step-3: Convert to floating-point on mask for the final result.
+  /* Step-4: Convert to floating-point on mask for the final result.
      To avoid unnecessary frm register access, we use RUP here and it will
      never do the rounding up because the tmp rtx comes from the float
      to int conversion.  */
-  rtx cvt_fp_ops[] = {op_0, mask, op_1, tmp};
-  icode = code_for_pred (FLOAT, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP_TAMU_FRM_RUP, cvt_fp_ops);
+  expand_vec_cvt_f_x (op_0, tmp, mask, UNARY_OP_TAMU_FRM_RUP, vec_fp_mode);
-  /* Step-4: Retrieve the sign bit.  */
+  /* Step-5: Retrieve the sign bit.  */
   expand_vec_copysign (op_0, op_0, op_1, vec_fp_mode);
}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
index 0959afd57d6..1c53d9b67d3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e16,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
index 142705b7eed..a6d0ac3fc83 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
index d232e36e1db..d196fc678c4 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
index 82e4f89a82a..cd3df49de6d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
--
2.34.1



^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2] RISC-V: Refine the code gen for ceil auto vectorization.
  2023-09-22 11:19 [PATCH v1] RISC-V: Refine the code gen for ceil auto vectorization pan2.li
  2023-09-22 11:25 ` juzhe.zhong
@ 2023-09-22 12:16 ` pan2.li
  2023-09-22 12:18   ` juzhe.zhong
  1 sibling, 1 reply; 6+ messages in thread
From: pan2.li @ 2023-09-22 12:16 UTC (permalink / raw)
  To: gcc-patches; +Cc: juzhe.zhong, pan2.li, yanzhang.wang, kito.cheng

From: Pan Li <pan2.li@intel.com>

We vectorized below ceil code already.

void
test_ceil (float *out, float *in, int count)
{
  for (unsigned i = 0; i < count; i++)
    out[i] = __builtin_ceilf (in[i]);
}

Before this patch:
vfmv.v.x    v4,fa0     // can be removed
vfabs.v     v0,v1
vmv1r.v     v2,v1      // can be removed
vmflt.vv    v0,v0,v4   // can be refined to vmflt.vf
vfcvt.x.f.v v3,v1,v0.t
vfcvt.f.x.v v2,v3,v0.t
vfsgnj.vv   v2,v2,v1

After this patch:
vfabs.v     v1,v2
vmflt.vf    v0,v1,fa5
vfcvt.x.f.v v3,v2,v0.t
vfcvt.f.x.v v1,v3,v0.t
vfsgnj.vv   v1,v1,v2

We can generate better code include below items.

* Remove vfmv.v.f.
* Take vmflt.vf instead of vmflt.vv.
* Remove vmv1r.v.

gcc/ChangeLog:

	* config/riscv/riscv-v.cc (expand_vec_float_cmp_mask): Refactor.
	(emit_vec_float_cmp_mask): Rename.
	(expand_vec_copysign): Ditto.
	(emit_vec_copysign): Ditto.
	(emit_vec_abs): New function impl.
	(emit_vec_cvt_x_f): Ditto.
	(emit_vec_cvt_f_x): Ditto.
	(expand_vec_ceil): Ditto.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c: Adjust body check.
	* gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c: Ditto.
	* gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c: Ditto.
	* gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c: Ditto.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/config/riscv/riscv-v.cc                   | 81 ++++++++++++-------
 .../riscv/rvv/autovec/unop/math-ceil-0.c      |  5 +-
 .../riscv/rvv/autovec/unop/math-ceil-1.c      |  5 +-
 .../riscv/rvv/autovec/unop/math-ceil-2.c      |  5 +-
 .../riscv/rvv/autovec/unop/math-ceil-3.c      |  5 +-
 5 files changed, 54 insertions(+), 47 deletions(-)

diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 4d0e1d8d1a9..251d827d973 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -3557,36 +3557,27 @@ gen_ceil_const_fp (machine_mode inner_mode)
 }
 
 static rtx
-expand_vec_float_cmp_mask (rtx fp_vector, rtx_code code, rtx fp_scalar,
-			   machine_mode vec_fp_mode)
+emit_vec_float_cmp_mask (rtx fp_vector, rtx_code code, rtx fp_scalar,
+			 machine_mode vec_fp_mode)
 {
-  /* Step-1: Get the abs float value for mask generation.  */
-  rtx tmp = gen_reg_rtx (vec_fp_mode);
-  rtx abs_ops[] = {tmp, fp_vector};
-  insn_code icode = code_for_pred (ABS, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP, abs_ops);
-
-  /* Step-2: Prepare the scalar float compare register.  */
+  /* Step-1: Prepare the scalar float compare register.  */
   rtx fp_reg = gen_reg_rtx (GET_MODE_INNER (vec_fp_mode));
   emit_insn (gen_move_insn (fp_reg, fp_scalar));
 
-  /* Step-3: Prepare the vector float compare register.  */
-  rtx vec_dup = gen_reg_rtx (vec_fp_mode);
-  icode = code_for_pred_broadcast (vec_fp_mode);
-  rtx vfmv_ops[] = {vec_dup, fp_reg};
-  emit_vlmax_insn (icode, UNARY_OP, vfmv_ops);
-
-  /* Step-4: Generate the mask.  */
+  /* Step-2: Generate the mask.  */
   machine_mode mask_mode = get_mask_mode (vec_fp_mode);
   rtx mask = gen_reg_rtx (mask_mode);
-  expand_vec_cmp (mask, code, tmp, vec_dup);
+  rtx cmp = gen_rtx_fmt_ee (code, mask_mode, fp_vector, fp_reg);
+  rtx cmp_ops[] = {mask, cmp, fp_vector, fp_reg};
+  insn_code icode = code_for_pred_cmp_scalar (vec_fp_mode);
+  emit_vlmax_insn (icode, COMPARE_OP, cmp_ops);
 
   return mask;
 }
 
 static void
-expand_vec_copysign (rtx op_dest, rtx op_src_0, rtx op_src_1,
-		     machine_mode vec_mode)
+emit_vec_copysign (rtx op_dest, rtx op_src_0, rtx op_src_1,
+		   machine_mode vec_mode)
 {
   rtx sgnj_ops[] = {op_dest, op_src_0, op_src_1};
   insn_code icode = code_for_pred (UNSPEC_VCOPYSIGN, vec_mode);
@@ -3594,30 +3585,58 @@ expand_vec_copysign (rtx op_dest, rtx op_src_0, rtx op_src_1,
   emit_vlmax_insn (icode, BINARY_OP, sgnj_ops);
 }
 
+static void
+emit_vec_abs (rtx op_dest, rtx op_src, machine_mode vec_mode)
+{
+  rtx abs_ops[] = {op_dest, op_src};
+  insn_code icode = code_for_pred (ABS, vec_mode);
+
+  emit_vlmax_insn (icode, UNARY_OP, abs_ops);
+}
+
+static void
+emit_vec_cvt_x_f (rtx op_dest, rtx op_src, rtx mask,
+		  insn_type type, machine_mode vec_mode)
+{
+  rtx cvt_x_ops[] = {op_dest, mask, op_dest, op_src};
+  insn_code icode = code_for_pred_fcvt_x_f (UNSPEC_VFCVT, vec_mode);
+
+  emit_vlmax_insn (icode, type, cvt_x_ops);
+}
+
+static void
+emit_vec_cvt_f_x (rtx op_dest, rtx op_src, rtx mask,
+		  insn_type type, machine_mode vec_mode)
+{
+  rtx cvt_fp_ops[] = {op_dest, mask, op_dest, op_src};
+  insn_code icode = code_for_pred (FLOAT, vec_mode);
+
+  emit_vlmax_insn (icode, type, cvt_fp_ops);
+}
+
 void
 expand_vec_ceil (rtx op_0, rtx op_1, machine_mode vec_fp_mode,
 		 machine_mode vec_int_mode)
 {
-  /* Step-1: Generate the mask on const fp.  */
+  /* Step-1: Get the abs float value for mask generation.  */
+  emit_vec_abs (op_0, op_1, vec_fp_mode);
+
+  /* Step-2: Generate the mask on const fp.  */
   rtx const_fp = gen_ceil_const_fp (GET_MODE_INNER (vec_fp_mode));
-  rtx mask = expand_vec_float_cmp_mask (op_1, LT, const_fp, vec_fp_mode);
+  rtx mask = emit_vec_float_cmp_mask (op_0, LT, const_fp, vec_fp_mode);
 
-  /* Step-2: Convert to integer on mask, with rounding up (aka ceil).  */
+  /* Step-3: Convert to integer on mask, with rounding up (aka ceil).  */
   rtx tmp = gen_reg_rtx (vec_int_mode);
-  rtx cvt_x_ops[] = {tmp, mask, tmp, op_1};
-  insn_code icode = code_for_pred_fcvt_x_f (UNSPEC_VFCVT, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP_TAMU_FRM_RUP, cvt_x_ops);
+  emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMU_FRM_RUP, vec_fp_mode);
 
-  /* Step-3: Convert to floating-point on mask for the final result.
+  /* Step-4: Convert to floating-point on mask for the final result.
      To avoid unnecessary frm register access, we use RUP here and it will
      never do the rounding up because the tmp rtx comes from the float
      to int conversion.  */
-  rtx cvt_fp_ops[] = {op_0, mask, op_1, tmp};
-  icode = code_for_pred (FLOAT, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP_TAMU_FRM_RUP, cvt_fp_ops);
+  emit_vec_cvt_f_x (op_0, tmp, mask, UNARY_OP_TAMU_FRM_RUP, vec_fp_mode);
 
-  /* Step-4: Retrieve the sign bit.  */
-  expand_vec_copysign (op_0, op_0, op_1, vec_fp_mode);
+  /* Step-5: Retrieve the sign bit.  */
+  emit_vec_copysign (op_0, op_0, op_1, vec_fp_mode);
 }
 
 } // namespace riscv_vector
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
index 0959afd57d6..1c53d9b67d3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
@@ -12,11 +12,8 @@
 **   ...
 **   vsetvli\s+[atx][0-9]+,\s*zero,\s*e16,\s*m1,\s*ta,\s*mu
 **   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
 **   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
 **   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
 **   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
 **   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
index 142705b7eed..a6d0ac3fc83 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
@@ -12,11 +12,8 @@
 **   ...
 **   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
 **   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
 **   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
 **   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
 **   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
 **   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
index d232e36e1db..d196fc678c4 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
@@ -12,11 +12,8 @@
 **   ...
 **   vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*mu
 **   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
 **   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
 **   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
 **   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
 **   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
index 82e4f89a82a..cd3df49de6d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
@@ -12,11 +12,8 @@
 **   ...
 **   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
 **   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
 **   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
 **   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
 **   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
 **   ...
-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] RISC-V: Refine the code gen for ceil auto vectorization.
  2023-09-22 12:16 ` [PATCH v2] " pan2.li
@ 2023-09-22 12:18   ` juzhe.zhong
  2023-09-22 12:30     ` Li, Pan2
  0 siblings, 1 reply; 6+ messages in thread
From: juzhe.zhong @ 2023-09-22 12:18 UTC (permalink / raw)
  To: pan2.li, gcc-patches; +Cc: pan2.li, yanzhang.wang, kito.cheng

[-- Attachment #1: Type: text/plain, Size: 9586 bytes --]

LGTM.



juzhe.zhong@rivai.ai
 
From: pan2.li
Date: 2023-09-22 20:16
To: gcc-patches
CC: juzhe.zhong; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v2] RISC-V: Refine the code gen for ceil auto vectorization.
From: Pan Li <pan2.li@intel.com>
 
We vectorized below ceil code already.
 
void
test_ceil (float *out, float *in, int count)
{
  for (unsigned i = 0; i < count; i++)
    out[i] = __builtin_ceilf (in[i]);
}
 
Before this patch:
vfmv.v.x    v4,fa0     // can be removed
vfabs.v     v0,v1
vmv1r.v     v2,v1      // can be removed
vmflt.vv    v0,v0,v4   // can be refined to vmflt.vf
vfcvt.x.f.v v3,v1,v0.t
vfcvt.f.x.v v2,v3,v0.t
vfsgnj.vv   v2,v2,v1
 
After this patch:
vfabs.v     v1,v2
vmflt.vf    v0,v1,fa5
vfcvt.x.f.v v3,v2,v0.t
vfcvt.f.x.v v1,v3,v0.t
vfsgnj.vv   v1,v1,v2
 
We can generate better code include below items.
 
* Remove vfmv.v.f.
* Take vmflt.vf instead of vmflt.vv.
* Remove vmv1r.v.
 
gcc/ChangeLog:
 
* config/riscv/riscv-v.cc (expand_vec_float_cmp_mask): Refactor.
(emit_vec_float_cmp_mask): Rename.
(expand_vec_copysign): Ditto.
(emit_vec_copysign): Ditto.
(emit_vec_abs): New function impl.
(emit_vec_cvt_x_f): Ditto.
(emit_vec_cvt_f_x): Ditto.
(expand_vec_ceil): Ditto.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c: Adjust body check.
* gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c: Ditto.
 
Signed-off-by: Pan Li <pan2.li@intel.com>
---
gcc/config/riscv/riscv-v.cc                   | 81 ++++++++++++-------
.../riscv/rvv/autovec/unop/math-ceil-0.c      |  5 +-
.../riscv/rvv/autovec/unop/math-ceil-1.c      |  5 +-
.../riscv/rvv/autovec/unop/math-ceil-2.c      |  5 +-
.../riscv/rvv/autovec/unop/math-ceil-3.c      |  5 +-
5 files changed, 54 insertions(+), 47 deletions(-)
 
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 4d0e1d8d1a9..251d827d973 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -3557,36 +3557,27 @@ gen_ceil_const_fp (machine_mode inner_mode)
}
static rtx
-expand_vec_float_cmp_mask (rtx fp_vector, rtx_code code, rtx fp_scalar,
-    machine_mode vec_fp_mode)
+emit_vec_float_cmp_mask (rtx fp_vector, rtx_code code, rtx fp_scalar,
+ machine_mode vec_fp_mode)
{
-  /* Step-1: Get the abs float value for mask generation.  */
-  rtx tmp = gen_reg_rtx (vec_fp_mode);
-  rtx abs_ops[] = {tmp, fp_vector};
-  insn_code icode = code_for_pred (ABS, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP, abs_ops);
-
-  /* Step-2: Prepare the scalar float compare register.  */
+  /* Step-1: Prepare the scalar float compare register.  */
   rtx fp_reg = gen_reg_rtx (GET_MODE_INNER (vec_fp_mode));
   emit_insn (gen_move_insn (fp_reg, fp_scalar));
-  /* Step-3: Prepare the vector float compare register.  */
-  rtx vec_dup = gen_reg_rtx (vec_fp_mode);
-  icode = code_for_pred_broadcast (vec_fp_mode);
-  rtx vfmv_ops[] = {vec_dup, fp_reg};
-  emit_vlmax_insn (icode, UNARY_OP, vfmv_ops);
-
-  /* Step-4: Generate the mask.  */
+  /* Step-2: Generate the mask.  */
   machine_mode mask_mode = get_mask_mode (vec_fp_mode);
   rtx mask = gen_reg_rtx (mask_mode);
-  expand_vec_cmp (mask, code, tmp, vec_dup);
+  rtx cmp = gen_rtx_fmt_ee (code, mask_mode, fp_vector, fp_reg);
+  rtx cmp_ops[] = {mask, cmp, fp_vector, fp_reg};
+  insn_code icode = code_for_pred_cmp_scalar (vec_fp_mode);
+  emit_vlmax_insn (icode, COMPARE_OP, cmp_ops);
   return mask;
}
static void
-expand_vec_copysign (rtx op_dest, rtx op_src_0, rtx op_src_1,
-      machine_mode vec_mode)
+emit_vec_copysign (rtx op_dest, rtx op_src_0, rtx op_src_1,
+    machine_mode vec_mode)
{
   rtx sgnj_ops[] = {op_dest, op_src_0, op_src_1};
   insn_code icode = code_for_pred (UNSPEC_VCOPYSIGN, vec_mode);
@@ -3594,30 +3585,58 @@ expand_vec_copysign (rtx op_dest, rtx op_src_0, rtx op_src_1,
   emit_vlmax_insn (icode, BINARY_OP, sgnj_ops);
}
+static void
+emit_vec_abs (rtx op_dest, rtx op_src, machine_mode vec_mode)
+{
+  rtx abs_ops[] = {op_dest, op_src};
+  insn_code icode = code_for_pred (ABS, vec_mode);
+
+  emit_vlmax_insn (icode, UNARY_OP, abs_ops);
+}
+
+static void
+emit_vec_cvt_x_f (rtx op_dest, rtx op_src, rtx mask,
+   insn_type type, machine_mode vec_mode)
+{
+  rtx cvt_x_ops[] = {op_dest, mask, op_dest, op_src};
+  insn_code icode = code_for_pred_fcvt_x_f (UNSPEC_VFCVT, vec_mode);
+
+  emit_vlmax_insn (icode, type, cvt_x_ops);
+}
+
+static void
+emit_vec_cvt_f_x (rtx op_dest, rtx op_src, rtx mask,
+   insn_type type, machine_mode vec_mode)
+{
+  rtx cvt_fp_ops[] = {op_dest, mask, op_dest, op_src};
+  insn_code icode = code_for_pred (FLOAT, vec_mode);
+
+  emit_vlmax_insn (icode, type, cvt_fp_ops);
+}
+
void
expand_vec_ceil (rtx op_0, rtx op_1, machine_mode vec_fp_mode,
machine_mode vec_int_mode)
{
-  /* Step-1: Generate the mask on const fp.  */
+  /* Step-1: Get the abs float value for mask generation.  */
+  emit_vec_abs (op_0, op_1, vec_fp_mode);
+
+  /* Step-2: Generate the mask on const fp.  */
   rtx const_fp = gen_ceil_const_fp (GET_MODE_INNER (vec_fp_mode));
-  rtx mask = expand_vec_float_cmp_mask (op_1, LT, const_fp, vec_fp_mode);
+  rtx mask = emit_vec_float_cmp_mask (op_0, LT, const_fp, vec_fp_mode);
-  /* Step-2: Convert to integer on mask, with rounding up (aka ceil).  */
+  /* Step-3: Convert to integer on mask, with rounding up (aka ceil).  */
   rtx tmp = gen_reg_rtx (vec_int_mode);
-  rtx cvt_x_ops[] = {tmp, mask, tmp, op_1};
-  insn_code icode = code_for_pred_fcvt_x_f (UNSPEC_VFCVT, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP_TAMU_FRM_RUP, cvt_x_ops);
+  emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMU_FRM_RUP, vec_fp_mode);
-  /* Step-3: Convert to floating-point on mask for the final result.
+  /* Step-4: Convert to floating-point on mask for the final result.
      To avoid unnecessary frm register access, we use RUP here and it will
      never do the rounding up because the tmp rtx comes from the float
      to int conversion.  */
-  rtx cvt_fp_ops[] = {op_0, mask, op_1, tmp};
-  icode = code_for_pred (FLOAT, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP_TAMU_FRM_RUP, cvt_fp_ops);
+  emit_vec_cvt_f_x (op_0, tmp, mask, UNARY_OP_TAMU_FRM_RUP, vec_fp_mode);
-  /* Step-4: Retrieve the sign bit.  */
-  expand_vec_copysign (op_0, op_0, op_1, vec_fp_mode);
+  /* Step-5: Retrieve the sign bit.  */
+  emit_vec_copysign (op_0, op_0, op_1, vec_fp_mode);
}
} // namespace riscv_vector
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
index 0959afd57d6..1c53d9b67d3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e16,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
index 142705b7eed..a6d0ac3fc83 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
index d232e36e1db..d196fc678c4 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
index 82e4f89a82a..cd3df49de6d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
-- 
2.34.1
 
 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [PATCH v2] RISC-V: Refine the code gen for ceil auto vectorization.
  2023-09-22 12:18   ` juzhe.zhong
@ 2023-09-22 12:30     ` Li, Pan2
  0 siblings, 0 replies; 6+ messages in thread
From: Li, Pan2 @ 2023-09-22 12:30 UTC (permalink / raw)
  To: juzhe.zhong, gcc-patches; +Cc: Wang, Yanzhang, kito.cheng

[-- Attachment #1: Type: text/plain, Size: 10251 bytes --]

Committed, thanks Juzhe.

Pan

From: juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai>
Sent: Friday, September 22, 2023 8:19 PM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: Li, Pan2 <pan2.li@intel.com>; Wang, Yanzhang <yanzhang.wang@intel.com>; kito.cheng <kito.cheng@gmail.com>
Subject: Re: [PATCH v2] RISC-V: Refine the code gen for ceil auto vectorization.

LGTM.

________________________________
juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>

From: pan2.li<mailto:pan2.li@intel.com>
Date: 2023-09-22 20:16
To: gcc-patches<mailto:gcc-patches@gcc.gnu.org>
CC: juzhe.zhong<mailto:juzhe.zhong@rivai.ai>; pan2.li<mailto:pan2.li@intel.com>; yanzhang.wang<mailto:yanzhang.wang@intel.com>; kito.cheng<mailto:kito.cheng@gmail.com>
Subject: [PATCH v2] RISC-V: Refine the code gen for ceil auto vectorization.
From: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>

We vectorized below ceil code already.

void
test_ceil (float *out, float *in, int count)
{
  for (unsigned i = 0; i < count; i++)
    out[i] = __builtin_ceilf (in[i]);
}

Before this patch:
vfmv.v.x    v4,fa0     // can be removed
vfabs.v     v0,v1
vmv1r.v     v2,v1      // can be removed
vmflt.vv    v0,v0,v4   // can be refined to vmflt.vf
vfcvt.x.f.v v3,v1,v0.t
vfcvt.f.x.v v2,v3,v0.t
vfsgnj.vv   v2,v2,v1

After this patch:
vfabs.v     v1,v2
vmflt.vf    v0,v1,fa5
vfcvt.x.f.v v3,v2,v0.t
vfcvt.f.x.v v1,v3,v0.t
vfsgnj.vv   v1,v1,v2

We can generate better code include below items.

* Remove vfmv.v.f.
* Take vmflt.vf instead of vmflt.vv.
* Remove vmv1r.v.

gcc/ChangeLog:

* config/riscv/riscv-v.cc (expand_vec_float_cmp_mask): Refactor.
(emit_vec_float_cmp_mask): Rename.
(expand_vec_copysign): Ditto.
(emit_vec_copysign): Ditto.
(emit_vec_abs): New function impl.
(emit_vec_cvt_x_f): Ditto.
(emit_vec_cvt_f_x): Ditto.
(expand_vec_ceil): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c: Adjust body check.
* gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c: Ditto.

Signed-off-by: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>
---
gcc/config/riscv/riscv-v.cc                   | 81 ++++++++++++-------
.../riscv/rvv/autovec/unop/math-ceil-0.c      |  5 +-
.../riscv/rvv/autovec/unop/math-ceil-1.c      |  5 +-
.../riscv/rvv/autovec/unop/math-ceil-2.c      |  5 +-
.../riscv/rvv/autovec/unop/math-ceil-3.c      |  5 +-
5 files changed, 54 insertions(+), 47 deletions(-)

diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 4d0e1d8d1a9..251d827d973 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -3557,36 +3557,27 @@ gen_ceil_const_fp (machine_mode inner_mode)
}
static rtx
-expand_vec_float_cmp_mask (rtx fp_vector, rtx_code code, rtx fp_scalar,
-    machine_mode vec_fp_mode)
+emit_vec_float_cmp_mask (rtx fp_vector, rtx_code code, rtx fp_scalar,
+ machine_mode vec_fp_mode)
{
-  /* Step-1: Get the abs float value for mask generation.  */
-  rtx tmp = gen_reg_rtx (vec_fp_mode);
-  rtx abs_ops[] = {tmp, fp_vector};
-  insn_code icode = code_for_pred (ABS, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP, abs_ops);
-
-  /* Step-2: Prepare the scalar float compare register.  */
+  /* Step-1: Prepare the scalar float compare register.  */
   rtx fp_reg = gen_reg_rtx (GET_MODE_INNER (vec_fp_mode));
   emit_insn (gen_move_insn (fp_reg, fp_scalar));
-  /* Step-3: Prepare the vector float compare register.  */
-  rtx vec_dup = gen_reg_rtx (vec_fp_mode);
-  icode = code_for_pred_broadcast (vec_fp_mode);
-  rtx vfmv_ops[] = {vec_dup, fp_reg};
-  emit_vlmax_insn (icode, UNARY_OP, vfmv_ops);
-
-  /* Step-4: Generate the mask.  */
+  /* Step-2: Generate the mask.  */
   machine_mode mask_mode = get_mask_mode (vec_fp_mode);
   rtx mask = gen_reg_rtx (mask_mode);
-  expand_vec_cmp (mask, code, tmp, vec_dup);
+  rtx cmp = gen_rtx_fmt_ee (code, mask_mode, fp_vector, fp_reg);
+  rtx cmp_ops[] = {mask, cmp, fp_vector, fp_reg};
+  insn_code icode = code_for_pred_cmp_scalar (vec_fp_mode);
+  emit_vlmax_insn (icode, COMPARE_OP, cmp_ops);
   return mask;
}
static void
-expand_vec_copysign (rtx op_dest, rtx op_src_0, rtx op_src_1,
-      machine_mode vec_mode)
+emit_vec_copysign (rtx op_dest, rtx op_src_0, rtx op_src_1,
+    machine_mode vec_mode)
{
   rtx sgnj_ops[] = {op_dest, op_src_0, op_src_1};
   insn_code icode = code_for_pred (UNSPEC_VCOPYSIGN, vec_mode);
@@ -3594,30 +3585,58 @@ expand_vec_copysign (rtx op_dest, rtx op_src_0, rtx op_src_1,
   emit_vlmax_insn (icode, BINARY_OP, sgnj_ops);
}
+static void
+emit_vec_abs (rtx op_dest, rtx op_src, machine_mode vec_mode)
+{
+  rtx abs_ops[] = {op_dest, op_src};
+  insn_code icode = code_for_pred (ABS, vec_mode);
+
+  emit_vlmax_insn (icode, UNARY_OP, abs_ops);
+}
+
+static void
+emit_vec_cvt_x_f (rtx op_dest, rtx op_src, rtx mask,
+   insn_type type, machine_mode vec_mode)
+{
+  rtx cvt_x_ops[] = {op_dest, mask, op_dest, op_src};
+  insn_code icode = code_for_pred_fcvt_x_f (UNSPEC_VFCVT, vec_mode);
+
+  emit_vlmax_insn (icode, type, cvt_x_ops);
+}
+
+static void
+emit_vec_cvt_f_x (rtx op_dest, rtx op_src, rtx mask,
+   insn_type type, machine_mode vec_mode)
+{
+  rtx cvt_fp_ops[] = {op_dest, mask, op_dest, op_src};
+  insn_code icode = code_for_pred (FLOAT, vec_mode);
+
+  emit_vlmax_insn (icode, type, cvt_fp_ops);
+}
+
void
expand_vec_ceil (rtx op_0, rtx op_1, machine_mode vec_fp_mode,
machine_mode vec_int_mode)
{
-  /* Step-1: Generate the mask on const fp.  */
+  /* Step-1: Get the abs float value for mask generation.  */
+  emit_vec_abs (op_0, op_1, vec_fp_mode);
+
+  /* Step-2: Generate the mask on const fp.  */
   rtx const_fp = gen_ceil_const_fp (GET_MODE_INNER (vec_fp_mode));
-  rtx mask = expand_vec_float_cmp_mask (op_1, LT, const_fp, vec_fp_mode);
+  rtx mask = emit_vec_float_cmp_mask (op_0, LT, const_fp, vec_fp_mode);
-  /* Step-2: Convert to integer on mask, with rounding up (aka ceil).  */
+  /* Step-3: Convert to integer on mask, with rounding up (aka ceil).  */
   rtx tmp = gen_reg_rtx (vec_int_mode);
-  rtx cvt_x_ops[] = {tmp, mask, tmp, op_1};
-  insn_code icode = code_for_pred_fcvt_x_f (UNSPEC_VFCVT, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP_TAMU_FRM_RUP, cvt_x_ops);
+  emit_vec_cvt_x_f (tmp, op_1, mask, UNARY_OP_TAMU_FRM_RUP, vec_fp_mode);
-  /* Step-3: Convert to floating-point on mask for the final result.
+  /* Step-4: Convert to floating-point on mask for the final result.
      To avoid unnecessary frm register access, we use RUP here and it will
      never do the rounding up because the tmp rtx comes from the float
      to int conversion.  */
-  rtx cvt_fp_ops[] = {op_0, mask, op_1, tmp};
-  icode = code_for_pred (FLOAT, vec_fp_mode);
-  emit_vlmax_insn (icode, UNARY_OP_TAMU_FRM_RUP, cvt_fp_ops);
+  emit_vec_cvt_f_x (op_0, tmp, mask, UNARY_OP_TAMU_FRM_RUP, vec_fp_mode);
-  /* Step-4: Retrieve the sign bit.  */
-  expand_vec_copysign (op_0, op_0, op_1, vec_fp_mode);
+  /* Step-5: Retrieve the sign bit.  */
+  emit_vec_copysign (op_0, op_0, op_1, vec_fp_mode);
}
} // namespace riscv_vector
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
index 0959afd57d6..1c53d9b67d3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-0.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e16,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
index 142705b7eed..a6d0ac3fc83 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-1.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
index d232e36e1db..d196fc678c4 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-2.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e64,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
index 82e4f89a82a..cd3df49de6d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/unop/math-ceil-3.c
@@ -12,11 +12,8 @@
**   ...
**   vsetvli\s+[atx][0-9]+,\s*zero,\s*e32,\s*m1,\s*ta,\s*mu
**   vfabs\.v\s+v[0-9]+,\s*v[0-9]+
-**   ...
-**   vmflt\.vv\s+v0,\s*v[0-9]+,\s*v[0-9]+
-**   ...
+**   vmflt\.vf\s+v0,\s*v[0-9]+,\s*[fa]+[0-9]+
**   vfcvt\.x\.f\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
-**   ...
**   vfcvt\.f\.x\.v\s+v[0-9]+,\s*v[0-9]+,\s*v0\.t
**   vfsgnj\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
**   ...
--
2.34.1



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-09-22 12:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-22 11:19 [PATCH v1] RISC-V: Refine the code gen for ceil auto vectorization pan2.li
2023-09-22 11:25 ` juzhe.zhong
2023-09-22 11:30   ` Li, Pan2
2023-09-22 12:16 ` [PATCH v2] " pan2.li
2023-09-22 12:18   ` juzhe.zhong
2023-09-22 12:30     ` Li, Pan2

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).