public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] [vect] Add vect_recog_cond_expr_convert_pattern.
@ 2022-01-24 13:01 liuhongt
  2022-02-08  8:48 ` Richard Biener
  0 siblings, 1 reply; 9+ messages in thread
From: liuhongt @ 2022-01-24 13:01 UTC (permalink / raw)
  To: gcc-patches

The pattern converts (cond (cmp a b) (convert c) (convert d))
to (convert (cond (cmp a b) c d)) when
1) types_match (c, d)
2) single_use for (convert c) and (convert d)
3) TYPE_PRECISION (TREE_TYPE (c)) == TYPE_PRECISION (TREE_TYPE (a))
4) INTEGERAL_TYPE_P (TREE_TYPE (c))

The pattern can save packing of mask and data(partial for data, 2 vs
1).

Bootstrapped and regtested for x86_64-pc-linux-gnu{-m32,}
and x86_64-pc-linux-gnu{-m32\ -march=native,\ -march=native} on CLX.
Ok for trunk?

gcc/ChangeLog:

	PR target/103771
	* match.pd (cond_expr_convert_p): New match.
	* tree-vect-patterns.cc (gimple_cond_expr_convert_p): Declare.
	(vect_recog_cond_expr_convert_pattern): New.

gcc/testsuite/ChangeLog:

	* gcc.target/i386/pr103771-2.c: New test.
---
 gcc/match.pd                               |  8 +++
 gcc/testsuite/gcc.target/i386/pr103771-2.c |  8 +++
 gcc/tree-vect-patterns.cc                  | 83 ++++++++++++++++++++++
 3 files changed, 99 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr103771-2.c

diff --git a/gcc/match.pd b/gcc/match.pd
index c68eed70a26..5808c4561ee 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -7647,3 +7647,11 @@ and,
    to the number of trailing zeroes.  */
 (match (ctz_table_index @1 @2 @3)
   (rshift (mult (bit_and:c (negate @1) @1) INTEGER_CST@2) INTEGER_CST@3))
+
+(match (cond_expr_convert_p @0 @2 @3 @6)
+ (cond (simple_comparison@6 @0 @1) (convert@4 @2) (convert@5 @3))
+  (if (types_match (TREE_TYPE (@2), TREE_TYPE (@3))
+       && INTEGRAL_TYPE_P (type)
+       && INTEGRAL_TYPE_P (TREE_TYPE (@2))
+       && single_use (@4)
+       && single_use (@5))))
diff --git a/gcc/testsuite/gcc.target/i386/pr103771-2.c b/gcc/testsuite/gcc.target/i386/pr103771-2.c
new file mode 100644
index 00000000000..962a3a74ecf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr103771-2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=cascadelake -O3" } */
+/* { dg-final { scan-assembler-not "kunpck" } } */
+/* { dg-final { scan-assembler-not "kand" } } */
+/* { dg-final { scan-assembler-not "kor" } } */
+/* { dg-final { scan-assembler-not "kshift" } } */
+
+#include "pr103771.c"
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index bea04992160..cbdfa96789c 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -924,6 +924,88 @@ vect_reassociating_reduction_p (vec_info *vinfo,
   return true;
 }
 
+/* match.pd function to match
+   (cond (cmp@3 a b) (convert@1 c) (convert@2 d))
+   with conditions:
+   1) there's single_use for both @1 and @2.
+   2) c and d have same type.
+   record a and c and d and @3.  */
+
+extern bool gimple_cond_expr_convert_p (tree, tree*, tree (*)(tree));
+
+/* Function vect_recog_cond_expr_convert
+
+   Try to find the following pattern:
+
+   TYPE1 A, B;
+   TYPE2 C,D;
+   TYPE3 E;
+   TYPE3 op_true = (TYPE3)A;
+   TYPE4 op_false = (TYPE3)B;
+
+   E = C cmp D ? op_true : op_false;
+
+   where
+   TYPE_PRECISION (TYPE1) != TYPE_PRECISION (TYPE3);
+   TYPE_PRECISION (TYPE1) == TYPE_PRECISION (TYPE2);
+   single_use of op_true and op_false.
+
+   Input:
+
+   * STMT_VINFO: The stmt from which the pattern search begins.
+   here it starts with E = c cmp D ? op_true : op_false;
+
+   Output:
+
+   TYPE1 E' = C cmp D ? A : B;
+   TYPE3 E = (TYPE3) E';
+
+   * TYPE_OUT: The vector type of the output of this pattern.
+
+   * Return value: A new stmt that will be used to replace the sequence of
+   stmts that constitute the pattern. In this case it will be:
+   E = (TYPE3)E';
+   E' = C cmp D ? A : B; is recorded in pattern definition statements;  */
+
+static gimple *
+vect_recog_cond_expr_convert_pattern (vec_info *vinfo,
+				      stmt_vec_info stmt_vinfo, tree *type_out)
+{
+  gassign *last_stmt = dyn_cast <gassign *> (stmt_vinfo->stmt);
+  tree lhs, match[4], temp, type, new_lhs;
+  gimple *cond_stmt;
+  gimple *pattern_stmt;
+
+  if (!last_stmt)
+    return NULL;
+
+  lhs = gimple_assign_lhs (last_stmt);
+
+  /* Find E = C cmp D ? (TYPE3) A ? (TYPE3) B;
+     TYPE_PRECISION (A) == TYPE_PRECISION (C).  */
+  if (!gimple_cond_expr_convert_p (lhs, &match[0], NULL)
+      || (TYPE_PRECISION (TREE_TYPE (match[0]))
+	  != TYPE_PRECISION (TREE_TYPE (match[1]))))
+    return NULL;
+
+  vect_pattern_detected ("vect_recog_cond_expr_convert_pattern", last_stmt);
+
+  type = TREE_TYPE (match[1]);
+  temp = vect_recog_temp_ssa_var (type, NULL);
+  cond_stmt = gimple_build_assign (temp, build3 (COND_EXPR, type, match[3],
+						 match[1], match[2]));
+  append_pattern_def_seq (vinfo, stmt_vinfo, cond_stmt,
+			  get_vectype_for_scalar_type (vinfo, type));
+  new_lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
+  pattern_stmt = gimple_build_assign (new_lhs, CONVERT_EXPR, temp);
+  *type_out = STMT_VINFO_VECTYPE (stmt_vinfo);
+
+  if (dump_enabled_p ())
+    dump_printf_loc (MSG_NOTE, vect_location,
+		     "created pattern stmt: %G", pattern_stmt);
+  return pattern_stmt;
+}
+
 /* Function vect_recog_dot_prod_pattern
 
    Try to find the following pattern:
@@ -5492,6 +5574,7 @@ static vect_recog_func vect_vect_recog_func_ptrs[] = {
   /* Must come after over_widening, which narrows the shift as much as
      possible beforehand.  */
   { vect_recog_average_pattern, "average" },
+  { vect_recog_cond_expr_convert_pattern, "cond_expr_convert" },
   { vect_recog_mulhs_pattern, "mult_high" },
   { vect_recog_cast_forwprop_pattern, "cast_forwprop" },
   { vect_recog_widen_mult_pattern, "widen_mult" },
-- 
2.18.1


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

* Re: [PATCH] [vect] Add vect_recog_cond_expr_convert_pattern.
  2022-01-24 13:01 [PATCH] [vect] Add vect_recog_cond_expr_convert_pattern liuhongt
@ 2022-02-08  8:48 ` Richard Biener
  2022-02-10  6:59   ` liuhongt
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Biener @ 2022-02-08  8:48 UTC (permalink / raw)
  To: liuhongt; +Cc: GCC Patches

On Mon, Jan 24, 2022 at 2:01 PM liuhongt via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> The pattern converts (cond (cmp a b) (convert c) (convert d))
> to (convert (cond (cmp a b) c d)) when
> 1) types_match (c, d)
> 2) single_use for (convert c) and (convert d)
> 3) TYPE_PRECISION (TREE_TYPE (c)) == TYPE_PRECISION (TREE_TYPE (a))
> 4) INTEGERAL_TYPE_P (TREE_TYPE (c))
>
> The pattern can save packing of mask and data(partial for data, 2 vs
> 1).
>
> Bootstrapped and regtested for x86_64-pc-linux-gnu{-m32,}
> and x86_64-pc-linux-gnu{-m32\ -march=native,\ -march=native} on CLX.
> Ok for trunk?

Sorry for the slow response, see for some comments below

> gcc/ChangeLog:
>
>         PR target/103771
>         * match.pd (cond_expr_convert_p): New match.
>         * tree-vect-patterns.cc (gimple_cond_expr_convert_p): Declare.
>         (vect_recog_cond_expr_convert_pattern): New.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/i386/pr103771-2.c: New test.
> ---
>  gcc/match.pd                               |  8 +++
>  gcc/testsuite/gcc.target/i386/pr103771-2.c |  8 +++
>  gcc/tree-vect-patterns.cc                  | 83 ++++++++++++++++++++++
>  3 files changed, 99 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr103771-2.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index c68eed70a26..5808c4561ee 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -7647,3 +7647,11 @@ and,
>     to the number of trailing zeroes.  */
>  (match (ctz_table_index @1 @2 @3)
>    (rshift (mult (bit_and:c (negate @1) @1) INTEGER_CST@2) INTEGER_CST@3))
> +
> +(match (cond_expr_convert_p @0 @2 @3 @6)
> + (cond (simple_comparison@6 @0 @1) (convert@4 @2) (convert@5 @3))
> +  (if (types_match (TREE_TYPE (@2), TREE_TYPE (@3))

But in principle @2 or @3 could safely differ in sign, you'd then need to ensure
to insert sign conversions to @2/@3 to the signedness of @4/@5.

> +       && INTEGRAL_TYPE_P (type)
> +       && INTEGRAL_TYPE_P (TREE_TYPE (@2))
> +       && single_use (@4)
> +       && single_use (@5))))
> diff --git a/gcc/testsuite/gcc.target/i386/pr103771-2.c b/gcc/testsuite/gcc.target/i386/pr103771-2.c
> new file mode 100644
> index 00000000000..962a3a74ecf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr103771-2.c
> @@ -0,0 +1,8 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=cascadelake -O3" } */
> +/* { dg-final { scan-assembler-not "kunpck" } } */
> +/* { dg-final { scan-assembler-not "kand" } } */
> +/* { dg-final { scan-assembler-not "kor" } } */
> +/* { dg-final { scan-assembler-not "kshift" } } */
> +
> +#include "pr103771.c"
> diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
> index bea04992160..cbdfa96789c 100644
> --- a/gcc/tree-vect-patterns.cc
> +++ b/gcc/tree-vect-patterns.cc
> @@ -924,6 +924,88 @@ vect_reassociating_reduction_p (vec_info *vinfo,
>    return true;
>  }
>
> +/* match.pd function to match
> +   (cond (cmp@3 a b) (convert@1 c) (convert@2 d))
> +   with conditions:
> +   1) there's single_use for both @1 and @2.
> +   2) c and d have same type.
> +   record a and c and d and @3.  */
> +
> +extern bool gimple_cond_expr_convert_p (tree, tree*, tree (*)(tree));
> +
> +/* Function vect_recog_cond_expr_convert
> +
> +   Try to find the following pattern:
> +
> +   TYPE1 A, B;
> +   TYPE2 C,D;
> +   TYPE3 E;
> +   TYPE3 op_true = (TYPE3)A;
> +   TYPE4 op_false = (TYPE3)B;
> +
> +   E = C cmp D ? op_true : op_false;
> +
> +   where
> +   TYPE_PRECISION (TYPE1) != TYPE_PRECISION (TYPE3);

you are not testing for this anywhere?

Btw, matching up the comments with the types is somewhat difficult,
maybe using TYPE_AB, TYPE_CD, TYPE_E instead of 1,2,3 will
make that easier ;)

> +   TYPE_PRECISION (TYPE1) == TYPE_PRECISION (TYPE2);
> +   single_use of op_true and op_false.
> +
> +   Input:
> +
> +   * STMT_VINFO: The stmt from which the pattern search begins.
> +   here it starts with E = c cmp D ? op_true : op_false;
> +
> +   Output:
> +
> +   TYPE1 E' = C cmp D ? A : B;
> +   TYPE3 E = (TYPE3) E';
> +
> +   * TYPE_OUT: The vector type of the output of this pattern.
> +
> +   * Return value: A new stmt that will be used to replace the sequence of
> +   stmts that constitute the pattern. In this case it will be:
> +   E = (TYPE3)E';
> +   E' = C cmp D ? A : B; is recorded in pattern definition statements;  */
> +
> +static gimple *
> +vect_recog_cond_expr_convert_pattern (vec_info *vinfo,
> +                                     stmt_vec_info stmt_vinfo, tree *type_out)
> +{
> +  gassign *last_stmt = dyn_cast <gassign *> (stmt_vinfo->stmt);
> +  tree lhs, match[4], temp, type, new_lhs;
> +  gimple *cond_stmt;
> +  gimple *pattern_stmt;
> +
> +  if (!last_stmt)
> +    return NULL;
> +
> +  lhs = gimple_assign_lhs (last_stmt);
> +
> +  /* Find E = C cmp D ? (TYPE3) A ? (TYPE3) B;
> +     TYPE_PRECISION (A) == TYPE_PRECISION (C).  */
> +  if (!gimple_cond_expr_convert_p (lhs, &match[0], NULL)
> +      || (TYPE_PRECISION (TREE_TYPE (match[0]))
> +         != TYPE_PRECISION (TREE_TYPE (match[1]))))

I think the precision check should be part of the match.pd pattern.  You
do not check that the comparison operands are integral - I think float
comparisons would be OK in principle but the precision check will not
work there.

Thanks,
Richard.

> +    return NULL;
> +
> +  vect_pattern_detected ("vect_recog_cond_expr_convert_pattern", last_stmt);
> +
> +  type = TREE_TYPE (match[1]);
> +  temp = vect_recog_temp_ssa_var (type, NULL);
> +  cond_stmt = gimple_build_assign (temp, build3 (COND_EXPR, type, match[3],
> +                                                match[1], match[2]));
> +  append_pattern_def_seq (vinfo, stmt_vinfo, cond_stmt,
> +                         get_vectype_for_scalar_type (vinfo, type));
> +  new_lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
> +  pattern_stmt = gimple_build_assign (new_lhs, CONVERT_EXPR, temp);
> +  *type_out = STMT_VINFO_VECTYPE (stmt_vinfo);
> +
> +  if (dump_enabled_p ())
> +    dump_printf_loc (MSG_NOTE, vect_location,
> +                    "created pattern stmt: %G", pattern_stmt);
> +  return pattern_stmt;
> +}
> +
>  /* Function vect_recog_dot_prod_pattern
>
>     Try to find the following pattern:
> @@ -5492,6 +5574,7 @@ static vect_recog_func vect_vect_recog_func_ptrs[] = {
>    /* Must come after over_widening, which narrows the shift as much as
>       possible beforehand.  */
>    { vect_recog_average_pattern, "average" },
> +  { vect_recog_cond_expr_convert_pattern, "cond_expr_convert" },
>    { vect_recog_mulhs_pattern, "mult_high" },
>    { vect_recog_cast_forwprop_pattern, "cast_forwprop" },
>    { vect_recog_widen_mult_pattern, "widen_mult" },
> --
> 2.18.1
>

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

* [PATCH] [vect] Add vect_recog_cond_expr_convert_pattern.
  2022-02-08  8:48 ` Richard Biener
@ 2022-02-10  6:59   ` liuhongt
  2022-02-11 12:29     ` Richard Biener
  0 siblings, 1 reply; 9+ messages in thread
From: liuhongt @ 2022-02-10  6:59 UTC (permalink / raw)
  To: gcc-patches

>But in principle @2 or @3 could safely differ in sign, you'd then need to ensure
>to insert sign conversions to @2/@3 to the signedness of @4/@5.
Changed.
>you are not testing for this anywhere?
It's tested in vect_recog_cond_expr_convert_pattern, I've move it to match.pd

>Btw, matching up the comments with the types is somewhat difficult,
>maybe using TYPE_AB, TYPE_CD, TYPE_E instead of 1,2,3 will
>make that easier ;)
Changed.
>I think the precision check should be part of the match.pd pattern.  You
>do not check that the comparison operands are integral - I think float
>comparisons would be OK in principle but the precision check will not
>work there.
Restricted to integeral type.

Here's updated patch.

gcc/ChangeLog:

	PR target/103771
	* match.pd (cond_expr_convert_p): New match.
	* tree-vect-patterns.cc (gimple_cond_expr_convert_p): Declare.
	(vect_recog_cond_expr_convert_pattern): New.

gcc/testsuite/ChangeLog:

	* gcc.target/i386/pr103771-2.c: New test.
	* gcc.target/i386/pr103771-3.c: New test.
---
 gcc/match.pd                               | 14 ++++
 gcc/testsuite/gcc.target/i386/pr103771-2.c |  8 ++
 gcc/testsuite/gcc.target/i386/pr103771-3.c | 21 +++++
 gcc/tree-vect-patterns.cc                  | 96 ++++++++++++++++++++++
 4 files changed, 139 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr103771-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr103771-3.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 7bbb80172fc..7386ee518a1 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -7683,3 +7683,17 @@ and,
    to the number of trailing zeroes.  */
 (match (ctz_table_index @1 @2 @3)
   (rshift (mult (bit_and:c (negate @1) @1) INTEGER_CST@2) INTEGER_CST@3))
+
+(match (cond_expr_convert_p @0 @2 @3 @6)
+ (cond (simple_comparison@6 @0 @1) (convert@4 @2) (convert@5 @3))
+  (if (INTEGRAL_TYPE_P (type)
+       && INTEGRAL_TYPE_P (TREE_TYPE (@2))
+       && INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && INTEGRAL_TYPE_P (TREE_TYPE (@3))
+       && TYPE_PRECISION (type) != TYPE_PRECISION (TREE_TYPE (@0))
+       && TYPE_PRECISION (TREE_TYPE (@0))
+	  == TYPE_PRECISION (TREE_TYPE (@2))
+       && TYPE_PRECISION (TREE_TYPE (@0))
+	  == TYPE_PRECISION (TREE_TYPE (@3))
+       && single_use (@4)
+       && single_use (@5))))
diff --git a/gcc/testsuite/gcc.target/i386/pr103771-2.c b/gcc/testsuite/gcc.target/i386/pr103771-2.c
new file mode 100644
index 00000000000..962a3a74ecf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr103771-2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=cascadelake -O3" } */
+/* { dg-final { scan-assembler-not "kunpck" } } */
+/* { dg-final { scan-assembler-not "kand" } } */
+/* { dg-final { scan-assembler-not "kor" } } */
+/* { dg-final { scan-assembler-not "kshift" } } */
+
+#include "pr103771.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr103771-3.c b/gcc/testsuite/gcc.target/i386/pr103771-3.c
new file mode 100644
index 00000000000..ef379b23b12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr103771-3.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=cascadelake -O3" } */
+/* { dg-final { scan-assembler-not "kunpck" } } */
+/* { dg-final { scan-assembler-not "kand" } } */
+/* { dg-final { scan-assembler-not "kor" } } */
+/* { dg-final { scan-assembler-not "kshift" } } */
+
+typedef unsigned char uint8_t;
+
+static uint8_t x264_clip_uint8 (int x, unsigned int y)
+{
+  return x & (~255) ? (-x) >> 31 : y;
+}
+
+void
+mc_weight (uint8_t* __restrict dst, uint8_t* __restrict src,
+	   int i_width,int i_scale, unsigned int* __restrict y)
+{
+  for(int x = 0; x < i_width; x++)
+    dst[x] = x264_clip_uint8 (src[x] * i_scale, y[x]);
+}
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index 2baf974627e..aa54bc8bf8b 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -924,6 +924,101 @@ vect_reassociating_reduction_p (vec_info *vinfo,
   return true;
 }
 
+/* match.pd function to match
+   (cond (cmp@3 a b) (convert@1 c) (convert@2 d))
+   with conditions:
+   1) @1, @2, c, d, a, b are all integral type.
+   2) There's single_use for both @1 and @2.
+   3) a, c and d have same precision.
+   4) c and @1 have different precision.
+
+   record a and c and d and @3.  */
+
+extern bool gimple_cond_expr_convert_p (tree, tree*, tree (*)(tree));
+
+/* Function vect_recog_cond_expr_convert
+
+   Try to find the following pattern:
+
+   TYPE_AB A,B;
+   TYPE_CD C,D;
+   TYPE_E E;
+   TYPE_E op_true = (TYPE_E) A;
+   TYPE_E op_false = (TYPE_E) B;
+
+   E = C cmp D ? op_true : op_false;
+
+   where
+   TYPE_PRECISION (TYPE_E) != TYPE_PRECISION (TYPE_CD);
+   TYPE_PRECISION (TYPE_AB) == TYPE_PRECISION (TYPE_CD);
+   single_use of op_true and op_false.
+   TYPE_AB could differ in sign.
+
+   Input:
+
+   * STMT_VINFO: The stmt from which the pattern search begins.
+   here it starts with E = c cmp D ? op_true : op_false;
+
+   Output:
+
+   TYPE1 E' = C cmp D ? A : B;
+   TYPE3 E = (TYPE3) E';
+
+   There may extra nop_convert for A or B to handle different signness.
+
+   * TYPE_OUT: The vector type of the output of this pattern.
+
+   * Return value: A new stmt that will be used to replace the sequence of
+   stmts that constitute the pattern. In this case it will be:
+   E = (TYPE3)E';
+   E' = C cmp D ? A : B; is recorded in pattern definition statements;  */
+
+static gimple *
+vect_recog_cond_expr_convert_pattern (vec_info *vinfo,
+				      stmt_vec_info stmt_vinfo, tree *type_out)
+{
+  gassign *last_stmt = dyn_cast <gassign *> (stmt_vinfo->stmt);
+  tree lhs, match[4], temp, type, new_lhs, op2;
+  gimple *cond_stmt;
+  gimple *pattern_stmt;
+
+  if (!last_stmt)
+    return NULL;
+
+  lhs = gimple_assign_lhs (last_stmt);
+
+  /* Find E = C cmp D ? (TYPE3) A ? (TYPE3) B;
+     TYPE_PRECISION (A) == TYPE_PRECISION (C).  */
+  if (!gimple_cond_expr_convert_p (lhs, &match[0], NULL))
+    return NULL;
+
+  vect_pattern_detected ("vect_recog_cond_expr_convert_pattern", last_stmt);
+
+  op2 = match[2];
+  type = TREE_TYPE (match[1]);
+  if (TYPE_SIGN (type) != TYPE_SIGN (TREE_TYPE (match[2])))
+    {
+      op2 = vect_recog_temp_ssa_var (type, NULL);
+      gimple* nop_stmt = gimple_build_assign (op2, CONVERT_EXPR, match[2]);
+      append_pattern_def_seq (vinfo, stmt_vinfo, nop_stmt,
+			      get_vectype_for_scalar_type (vinfo, type));
+    }
+
+  temp = vect_recog_temp_ssa_var (type, NULL);
+  cond_stmt = gimple_build_assign (temp, build3 (COND_EXPR, type, match[3],
+						 match[1], op2));
+  append_pattern_def_seq (vinfo, stmt_vinfo, cond_stmt,
+			  get_vectype_for_scalar_type (vinfo, type));
+  new_lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
+  pattern_stmt = gimple_build_assign (new_lhs, CONVERT_EXPR, temp);
+  *type_out = STMT_VINFO_VECTYPE (stmt_vinfo);
+
+  if (dump_enabled_p ())
+    dump_printf_loc (MSG_NOTE, vect_location,
+		     "created pattern stmt: %G", pattern_stmt);
+  return pattern_stmt;
+}
+
 /* Function vect_recog_dot_prod_pattern
 
    Try to find the following pattern:
@@ -5492,6 +5587,7 @@ static vect_recog_func vect_vect_recog_func_ptrs[] = {
   /* Must come after over_widening, which narrows the shift as much as
      possible beforehand.  */
   { vect_recog_average_pattern, "average" },
+  { vect_recog_cond_expr_convert_pattern, "cond_expr_convert" },
   { vect_recog_mulhs_pattern, "mult_high" },
   { vect_recog_cast_forwprop_pattern, "cast_forwprop" },
   { vect_recog_widen_mult_pattern, "widen_mult" },
-- 
2.18.1


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

* Re: [PATCH] [vect] Add vect_recog_cond_expr_convert_pattern.
  2022-02-10  6:59   ` liuhongt
@ 2022-02-11 12:29     ` Richard Biener
  2022-02-16  9:03       ` [PATCH] Restrict the two sources of vect_recog_cond_expr_convert_pattern to be of the same type when convert is extension liuhongt
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Biener @ 2022-02-11 12:29 UTC (permalink / raw)
  To: liuhongt; +Cc: GCC Patches

On Thu, Feb 10, 2022 at 7:59 AM liuhongt <hongtao.liu@intel.com> wrote:
>
> >But in principle @2 or @3 could safely differ in sign, you'd then need to ensure
> >to insert sign conversions to @2/@3 to the signedness of @4/@5.
> Changed.
> >you are not testing for this anywhere?
> It's tested in vect_recog_cond_expr_convert_pattern, I've move it to match.pd
>
> >Btw, matching up the comments with the types is somewhat difficult,
> >maybe using TYPE_AB, TYPE_CD, TYPE_E instead of 1,2,3 will
> >make that easier ;)
> Changed.
> >I think the precision check should be part of the match.pd pattern.  You
> >do not check that the comparison operands are integral - I think float
> >comparisons would be OK in principle but the precision check will not
> >work there.
> Restricted to integeral type.
>
> Here's updated patch.
>
> gcc/ChangeLog:
>
>         PR target/103771
>         * match.pd (cond_expr_convert_p): New match.
>         * tree-vect-patterns.cc (gimple_cond_expr_convert_p): Declare.
>         (vect_recog_cond_expr_convert_pattern): New.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/i386/pr103771-2.c: New test.
>         * gcc.target/i386/pr103771-3.c: New test.
> ---
>  gcc/match.pd                               | 14 ++++
>  gcc/testsuite/gcc.target/i386/pr103771-2.c |  8 ++
>  gcc/testsuite/gcc.target/i386/pr103771-3.c | 21 +++++
>  gcc/tree-vect-patterns.cc                  | 96 ++++++++++++++++++++++
>  4 files changed, 139 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr103771-2.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr103771-3.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 7bbb80172fc..7386ee518a1 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -7683,3 +7683,17 @@ and,
>     to the number of trailing zeroes.  */
>  (match (ctz_table_index @1 @2 @3)
>    (rshift (mult (bit_and:c (negate @1) @1) INTEGER_CST@2) INTEGER_CST@3))
> +
> +(match (cond_expr_convert_p @0 @2 @3 @6)
> + (cond (simple_comparison@6 @0 @1) (convert@4 @2) (convert@5 @3))
> +  (if (INTEGRAL_TYPE_P (type)
> +       && INTEGRAL_TYPE_P (TREE_TYPE (@2))
> +       && INTEGRAL_TYPE_P (TREE_TYPE (@0))
> +       && INTEGRAL_TYPE_P (TREE_TYPE (@3))
> +       && TYPE_PRECISION (type) != TYPE_PRECISION (TREE_TYPE (@0))
> +       && TYPE_PRECISION (TREE_TYPE (@0))
> +         == TYPE_PRECISION (TREE_TYPE (@2))
> +       && TYPE_PRECISION (TREE_TYPE (@0))
> +         == TYPE_PRECISION (TREE_TYPE (@3))
> +       && single_use (@4)
> +       && single_use (@5))))
> diff --git a/gcc/testsuite/gcc.target/i386/pr103771-2.c b/gcc/testsuite/gcc.target/i386/pr103771-2.c
> new file mode 100644
> index 00000000000..962a3a74ecf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr103771-2.c
> @@ -0,0 +1,8 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=cascadelake -O3" } */
> +/* { dg-final { scan-assembler-not "kunpck" } } */
> +/* { dg-final { scan-assembler-not "kand" } } */
> +/* { dg-final { scan-assembler-not "kor" } } */
> +/* { dg-final { scan-assembler-not "kshift" } } */
> +
> +#include "pr103771.c"
> diff --git a/gcc/testsuite/gcc.target/i386/pr103771-3.c b/gcc/testsuite/gcc.target/i386/pr103771-3.c
> new file mode 100644
> index 00000000000..ef379b23b12
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr103771-3.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=cascadelake -O3" } */
> +/* { dg-final { scan-assembler-not "kunpck" } } */
> +/* { dg-final { scan-assembler-not "kand" } } */
> +/* { dg-final { scan-assembler-not "kor" } } */
> +/* { dg-final { scan-assembler-not "kshift" } } */
> +
> +typedef unsigned char uint8_t;
> +
> +static uint8_t x264_clip_uint8 (int x, unsigned int y)
> +{
> +  return x & (~255) ? (-x) >> 31 : y;
> +}
> +
> +void
> +mc_weight (uint8_t* __restrict dst, uint8_t* __restrict src,
> +          int i_width,int i_scale, unsigned int* __restrict y)
> +{
> +  for(int x = 0; x < i_width; x++)
> +    dst[x] = x264_clip_uint8 (src[x] * i_scale, y[x]);
> +}
> diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
> index 2baf974627e..aa54bc8bf8b 100644
> --- a/gcc/tree-vect-patterns.cc
> +++ b/gcc/tree-vect-patterns.cc
> @@ -924,6 +924,101 @@ vect_reassociating_reduction_p (vec_info *vinfo,
>    return true;
>  }
>
> +/* match.pd function to match
> +   (cond (cmp@3 a b) (convert@1 c) (convert@2 d))
> +   with conditions:
> +   1) @1, @2, c, d, a, b are all integral type.
> +   2) There's single_use for both @1 and @2.
> +   3) a, c and d have same precision.
> +   4) c and @1 have different precision.
> +
> +   record a and c and d and @3.  */
> +
> +extern bool gimple_cond_expr_convert_p (tree, tree*, tree (*)(tree));
> +
> +/* Function vect_recog_cond_expr_convert
> +
> +   Try to find the following pattern:
> +
> +   TYPE_AB A,B;
> +   TYPE_CD C,D;
> +   TYPE_E E;
> +   TYPE_E op_true = (TYPE_E) A;
> +   TYPE_E op_false = (TYPE_E) B;
> +
> +   E = C cmp D ? op_true : op_false;
> +
> +   where
> +   TYPE_PRECISION (TYPE_E) != TYPE_PRECISION (TYPE_CD);
> +   TYPE_PRECISION (TYPE_AB) == TYPE_PRECISION (TYPE_CD);
> +   single_use of op_true and op_false.
> +   TYPE_AB could differ in sign.
> +
> +   Input:
> +
> +   * STMT_VINFO: The stmt from which the pattern search begins.
> +   here it starts with E = c cmp D ? op_true : op_false;
> +
> +   Output:
> +
> +   TYPE1 E' = C cmp D ? A : B;
> +   TYPE3 E = (TYPE3) E';
> +
> +   There may extra nop_convert for A or B to handle different signness.
> +
> +   * TYPE_OUT: The vector type of the output of this pattern.
> +
> +   * Return value: A new stmt that will be used to replace the sequence of
> +   stmts that constitute the pattern. In this case it will be:
> +   E = (TYPE3)E';
> +   E' = C cmp D ? A : B; is recorded in pattern definition statements;  */
> +
> +static gimple *
> +vect_recog_cond_expr_convert_pattern (vec_info *vinfo,
> +                                     stmt_vec_info stmt_vinfo, tree *type_out)
> +{
> +  gassign *last_stmt = dyn_cast <gassign *> (stmt_vinfo->stmt);
> +  tree lhs, match[4], temp, type, new_lhs, op2;
> +  gimple *cond_stmt;
> +  gimple *pattern_stmt;
> +
> +  if (!last_stmt)
> +    return NULL;
> +
> +  lhs = gimple_assign_lhs (last_stmt);
> +
> +  /* Find E = C cmp D ? (TYPE3) A ? (TYPE3) B;
> +     TYPE_PRECISION (A) == TYPE_PRECISION (C).  */
> +  if (!gimple_cond_expr_convert_p (lhs, &match[0], NULL))
> +    return NULL;
> +
> +  vect_pattern_detected ("vect_recog_cond_expr_convert_pattern", last_stmt);
> +
> +  op2 = match[2];
> +  type = TREE_TYPE (match[1]);
> +  if (TYPE_SIGN (type) != TYPE_SIGN (TREE_TYPE (match[2])))
> +    {
> +      op2 = vect_recog_temp_ssa_var (type, NULL);
> +      gimple* nop_stmt = gimple_build_assign (op2, CONVERT_EXPR, match[2]);

Please use NOP_EXPR here ...

> +      append_pattern_def_seq (vinfo, stmt_vinfo, nop_stmt,
> +                             get_vectype_for_scalar_type (vinfo, type));
> +    }
> +
> +  temp = vect_recog_temp_ssa_var (type, NULL);
> +  cond_stmt = gimple_build_assign (temp, build3 (COND_EXPR, type, match[3],
> +                                                match[1], op2));
> +  append_pattern_def_seq (vinfo, stmt_vinfo, cond_stmt,
> +                         get_vectype_for_scalar_type (vinfo, type));
> +  new_lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL);
> +  pattern_stmt = gimple_build_assign (new_lhs, CONVERT_EXPR, temp);

... and here.  OK with that change.

Thanks,
Richard.

> +  *type_out = STMT_VINFO_VECTYPE (stmt_vinfo);
> +
> +  if (dump_enabled_p ())
> +    dump_printf_loc (MSG_NOTE, vect_location,
> +                    "created pattern stmt: %G", pattern_stmt);
> +  return pattern_stmt;
> +}
> +
>  /* Function vect_recog_dot_prod_pattern
>
>     Try to find the following pattern:
> @@ -5492,6 +5587,7 @@ static vect_recog_func vect_vect_recog_func_ptrs[] = {
>    /* Must come after over_widening, which narrows the shift as much as
>       possible beforehand.  */
>    { vect_recog_average_pattern, "average" },
> +  { vect_recog_cond_expr_convert_pattern, "cond_expr_convert" },
>    { vect_recog_mulhs_pattern, "mult_high" },
>    { vect_recog_cast_forwprop_pattern, "cast_forwprop" },
>    { vect_recog_widen_mult_pattern, "widen_mult" },
> --
> 2.18.1
>

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

* [PATCH] Restrict the two sources of vect_recog_cond_expr_convert_pattern to be of the same type when convert is extension.
  2022-02-11 12:29     ` Richard Biener
@ 2022-02-16  9:03       ` liuhongt
  2022-02-16 14:15         ` Jakub Jelinek
  0 siblings, 1 reply; 9+ messages in thread
From: liuhongt @ 2022-02-16  9:03 UTC (permalink / raw)
  To: gcc-patches

> > +(match (cond_expr_convert_p @0 @2 @3 @6)
> > + (cond (simple_comparison@6 @0 @1) (convert@4 @2) (convert@5 @3))
> > +  (if (types_match (TREE_TYPE (@2), TREE_TYPE (@3))
>
> But in principle @2 or @3 could safely differ in sign, you'd then need to ensure
> to insert sign conversions to @2/@3 to the signedness of @4/@5.
>
It turns out differ in sign is not suitable for extension(but ok for truncation),
because it's zero_extend vs sign_extend.

The patch add types_match check when convert is extension.

Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
And native Bootstrapped and regtested on CLX.

Ok for trunk?

gcc/ChangeLog:

	PR tree-optimization/104551
	PR tree-optimization/103771
	* match.pd (cond_expr_convert_p): Add types_match check when
	convert is extension.
	* tree-vect-patterns.cc
	(gimple_cond_expr_convert_p): Adjust comments.
	(vect_recog_cond_expr_convert_pattern): Ditto.

gcc/testsuite/ChangeLog:

	* gcc.target/i386/pr104551.c: New test.
---
 gcc/match.pd                             |  8 +++++---
 gcc/testsuite/gcc.target/i386/pr104551.c | 24 ++++++++++++++++++++++++
 gcc/tree-vect-patterns.cc                |  6 ++++--
 3 files changed, 33 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr104551.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 05a10ab6bfd..8e80b9f1576 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -7692,11 +7692,13 @@ and,
   (if (INTEGRAL_TYPE_P (type)
        && INTEGRAL_TYPE_P (TREE_TYPE (@2))
        && INTEGRAL_TYPE_P (TREE_TYPE (@0))
-       && INTEGRAL_TYPE_P (TREE_TYPE (@3))
        && TYPE_PRECISION (type) != TYPE_PRECISION (TREE_TYPE (@0))
        && TYPE_PRECISION (TREE_TYPE (@0))
 	  == TYPE_PRECISION (TREE_TYPE (@2))
-       && TYPE_PRECISION (TREE_TYPE (@0))
-	  == TYPE_PRECISION (TREE_TYPE (@3))
+       && (types_match (TREE_TYPE (@2), TREE_TYPE (@3))
+	   || ((TYPE_PRECISION (TREE_TYPE (@0))
+		== TYPE_PRECISION (TREE_TYPE (@3)))
+	       && INTEGRAL_TYPE_P (TREE_TYPE (@3))
+	       && TYPE_PRECISION (TREE_TYPE (@3)) > TYPE_PRECISION (type)))
        && single_use (@4)
        && single_use (@5))))
diff --git a/gcc/testsuite/gcc.target/i386/pr104551.c b/gcc/testsuite/gcc.target/i386/pr104551.c
new file mode 100644
index 00000000000..6300f25c0d5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr104551.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -mavx2" } */
+/* { dg-require-effective-target avx2 } */
+
+unsigned int
+__attribute__((noipa))
+test(unsigned int a, unsigned char p[16]) {
+  unsigned int res = 0;
+  for (unsigned b = 0; b < a; b += 1)
+    res = p[b] ? p[b] : (char) b;
+  return res;
+}
+
+int main ()
+{
+  unsigned int a = 16U;
+  unsigned char p[16];
+  for (int i = 0; i != 16; i++)
+    p[i] = (unsigned char)128;
+  unsigned int res = test (a, p);
+  if (res != 128)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index a8f96d59643..217bdfd7045 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -929,8 +929,10 @@ vect_reassociating_reduction_p (vec_info *vinfo,
    with conditions:
    1) @1, @2, c, d, a, b are all integral type.
    2) There's single_use for both @1 and @2.
-   3) a, c and d have same precision.
+   3) a, c have same precision.
    4) c and @1 have different precision.
+   5) c, d are the same type or they can differ in sign when convert is
+   truncation.
 
    record a and c and d and @3.  */
 
@@ -952,7 +954,7 @@ extern bool gimple_cond_expr_convert_p (tree, tree*, tree (*)(tree));
    TYPE_PRECISION (TYPE_E) != TYPE_PRECISION (TYPE_CD);
    TYPE_PRECISION (TYPE_AB) == TYPE_PRECISION (TYPE_CD);
    single_use of op_true and op_false.
-   TYPE_AB could differ in sign.
+   TYPE_AB could differ in sign when (TYPE_E) A is a truncation.
 
    Input:
 
-- 
2.18.1


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

* Re: [PATCH] Restrict the two sources of vect_recog_cond_expr_convert_pattern to be of the same type when convert is extension.
  2022-02-16  9:03       ` [PATCH] Restrict the two sources of vect_recog_cond_expr_convert_pattern to be of the same type when convert is extension liuhongt
@ 2022-02-16 14:15         ` Jakub Jelinek
  2022-02-17  1:30           ` Hongtao Liu
  0 siblings, 1 reply; 9+ messages in thread
From: Jakub Jelinek @ 2022-02-16 14:15 UTC (permalink / raw)
  To: liuhongt; +Cc: gcc-patches

On Wed, Feb 16, 2022 at 05:03:09PM +0800, liuhongt via Gcc-patches wrote:
> > > +(match (cond_expr_convert_p @0 @2 @3 @6)
> > > + (cond (simple_comparison@6 @0 @1) (convert@4 @2) (convert@5 @3))
> > > +  (if (types_match (TREE_TYPE (@2), TREE_TYPE (@3))
> >
> > But in principle @2 or @3 could safely differ in sign, you'd then need to ensure
> > to insert sign conversions to @2/@3 to the signedness of @4/@5.
> >
> It turns out differ in sign is not suitable for extension(but ok for truncation),
> because it's zero_extend vs sign_extend.
> 
> The patch add types_match check when convert is extension.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> And native Bootstrapped and regtested on CLX.
> 
> Ok for trunk?
> 
> gcc/ChangeLog:
> 
> 	PR tree-optimization/104551
> 	PR tree-optimization/103771
> 	* match.pd (cond_expr_convert_p): Add types_match check when
> 	convert is extension.
> 	* tree-vect-patterns.cc
> 	(gimple_cond_expr_convert_p): Adjust comments.
> 	(vect_recog_cond_expr_convert_pattern): Ditto.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.target/i386/pr104551.c: New test.
> ---
>  gcc/match.pd                             |  8 +++++---
>  gcc/testsuite/gcc.target/i386/pr104551.c | 24 ++++++++++++++++++++++++
>  gcc/tree-vect-patterns.cc                |  6 ++++--
>  3 files changed, 33 insertions(+), 5 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr104551.c
> 
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 05a10ab6bfd..8e80b9f1576 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -7692,11 +7692,13 @@ and,
>    (if (INTEGRAL_TYPE_P (type)
>         && INTEGRAL_TYPE_P (TREE_TYPE (@2))
>         && INTEGRAL_TYPE_P (TREE_TYPE (@0))
> -       && INTEGRAL_TYPE_P (TREE_TYPE (@3))
>         && TYPE_PRECISION (type) != TYPE_PRECISION (TREE_TYPE (@0))
>         && TYPE_PRECISION (TREE_TYPE (@0))
>  	  == TYPE_PRECISION (TREE_TYPE (@2))
> -       && TYPE_PRECISION (TREE_TYPE (@0))
> -	  == TYPE_PRECISION (TREE_TYPE (@3))
> +       && (types_match (TREE_TYPE (@2), TREE_TYPE (@3))
> +	   || ((TYPE_PRECISION (TREE_TYPE (@0))
> +		== TYPE_PRECISION (TREE_TYPE (@3)))
> +	       && INTEGRAL_TYPE_P (TREE_TYPE (@3))
> +	       && TYPE_PRECISION (TREE_TYPE (@3)) > TYPE_PRECISION (type)))
>         && single_use (@4)
>         && single_use (@5))))

I find this quite unreadable, it looks like if @2 and @3 are treated
differently.  I think keeping the old 3 lines and just adding
      && (TYPE_PRECISION (TREE_TYPE (@0)) >= TYPE_PRECISION (type)
	  || (TYPE_UNSIGNED (TREE_TYPE (@2))
	      == TYPE_UNSIGNED (TREE_TYPE (@3))))
after it ideally with a comment why would be better.
Note, if the precision of @0 and type is the same, I think signedness can
still differ, no?

	Jakub


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

* Re: [PATCH] Restrict the two sources of vect_recog_cond_expr_convert_pattern to be of the same type when convert is extension.
  2022-02-16 14:15         ` Jakub Jelinek
@ 2022-02-17  1:30           ` Hongtao Liu
  2022-02-17  5:31             ` [PATCH V2] " liuhongt
  0 siblings, 1 reply; 9+ messages in thread
From: Hongtao Liu @ 2022-02-17  1:30 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: liuhongt, GCC Patches

On Wed, Feb 16, 2022 at 10:17 PM Jakub Jelinek via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On Wed, Feb 16, 2022 at 05:03:09PM +0800, liuhongt via Gcc-patches wrote:
> > > > +(match (cond_expr_convert_p @0 @2 @3 @6)
> > > > + (cond (simple_comparison@6 @0 @1) (convert@4 @2) (convert@5 @3))
> > > > +  (if (types_match (TREE_TYPE (@2), TREE_TYPE (@3))
> > >
> > > But in principle @2 or @3 could safely differ in sign, you'd then need to ensure
> > > to insert sign conversions to @2/@3 to the signedness of @4/@5.
> > >
> > It turns out differ in sign is not suitable for extension(but ok for truncation),
> > because it's zero_extend vs sign_extend.
> >
> > The patch add types_match check when convert is extension.
> >
> > Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> > And native Bootstrapped and regtested on CLX.
> >
> > Ok for trunk?
> >
> > gcc/ChangeLog:
> >
> >       PR tree-optimization/104551
> >       PR tree-optimization/103771
> >       * match.pd (cond_expr_convert_p): Add types_match check when
> >       convert is extension.
> >       * tree-vect-patterns.cc
> >       (gimple_cond_expr_convert_p): Adjust comments.
> >       (vect_recog_cond_expr_convert_pattern): Ditto.
> >
> > gcc/testsuite/ChangeLog:
> >
> >       * gcc.target/i386/pr104551.c: New test.
> > ---
> >  gcc/match.pd                             |  8 +++++---
> >  gcc/testsuite/gcc.target/i386/pr104551.c | 24 ++++++++++++++++++++++++
> >  gcc/tree-vect-patterns.cc                |  6 ++++--
> >  3 files changed, 33 insertions(+), 5 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr104551.c
> >
> > diff --git a/gcc/match.pd b/gcc/match.pd
> > index 05a10ab6bfd..8e80b9f1576 100644
> > --- a/gcc/match.pd
> > +++ b/gcc/match.pd
> > @@ -7692,11 +7692,13 @@ and,
> >    (if (INTEGRAL_TYPE_P (type)
> >         && INTEGRAL_TYPE_P (TREE_TYPE (@2))
> >         && INTEGRAL_TYPE_P (TREE_TYPE (@0))
> > -       && INTEGRAL_TYPE_P (TREE_TYPE (@3))
> >         && TYPE_PRECISION (type) != TYPE_PRECISION (TREE_TYPE (@0))
> >         && TYPE_PRECISION (TREE_TYPE (@0))
> >         == TYPE_PRECISION (TREE_TYPE (@2))
> > -       && TYPE_PRECISION (TREE_TYPE (@0))
> > -       == TYPE_PRECISION (TREE_TYPE (@3))
> > +       && (types_match (TREE_TYPE (@2), TREE_TYPE (@3))
> > +        || ((TYPE_PRECISION (TREE_TYPE (@0))
> > +             == TYPE_PRECISION (TREE_TYPE (@3)))
> > +            && INTEGRAL_TYPE_P (TREE_TYPE (@3))
> > +            && TYPE_PRECISION (TREE_TYPE (@3)) > TYPE_PRECISION (type)))
> >         && single_use (@4)
> >         && single_use (@5))))
>
> I find this quite unreadable, it looks like if @2 and @3 are treated
> differently.  I think keeping the old 3 lines and just adding
>       && (TYPE_PRECISION (TREE_TYPE (@0)) >= TYPE_PRECISION (type)
>           || (TYPE_UNSIGNED (TREE_TYPE (@2))
>               == TYPE_UNSIGNED (TREE_TYPE (@3))))
Yes, good idea.
> after it ideally with a comment why would be better.
> Note, if the precision of @0 and type is the same, I think signedness can
> still differ, no?
We have TYPE_PRECISION (type) != TYPE_PRECISION (TREE_TYPE (@0)).
>
>         Jakub
>


-- 
BR,
Hongtao

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

* [PATCH V2] Restrict the two sources of vect_recog_cond_expr_convert_pattern to be of the same type when convert is extension.
  2022-02-17  1:30           ` Hongtao Liu
@ 2022-02-17  5:31             ` liuhongt
  2022-02-17  9:48               ` Richard Biener
  0 siblings, 1 reply; 9+ messages in thread
From: liuhongt @ 2022-02-17  5:31 UTC (permalink / raw)
  To: gcc-patches; +Cc: jakub

> I find this quite unreadable, it looks like if @2 and @3 are treated
> differently.  I think keeping the old 3 lines and just adding
>       && (TYPE_PRECISION (TREE_TYPE (@0)) >= TYPE_PRECISION (type)
>           || (TYPE_UNSIGNED (TREE_TYPE (@2))
>               == TYPE_UNSIGNED (TREE_TYPE (@3))))
> after it ideally with a comment why would be better.
Update patch.

gcc/ChangeLog:

	PR tree-optimization/104551
	PR tree-optimization/103771
	* match.pd (cond_expr_convert_p): Add types_match check when
	convert is extension.
	* tree-vect-patterns.cc
	(gimple_cond_expr_convert_p): Adjust comments.
	(vect_recog_cond_expr_convert_pattern): Ditto.

gcc/testsuite/ChangeLog:

	* gcc.target/i386/pr104551.c: New test.
---
 gcc/match.pd                             |  6 ++++++
 gcc/testsuite/gcc.target/i386/pr104551.c | 24 ++++++++++++++++++++++++
 gcc/tree-vect-patterns.cc                |  6 ++++--
 3 files changed, 34 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr104551.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 05a10ab6bfd..8b6f22f1065 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -7698,5 +7698,11 @@ and,
 	  == TYPE_PRECISION (TREE_TYPE (@2))
        && TYPE_PRECISION (TREE_TYPE (@0))
 	  == TYPE_PRECISION (TREE_TYPE (@3))
+       /* For vect_recog_cond_expr_convert_pattern, @2 and @3 can differ in
+	  signess when convert is truncation, but not ok for extension since
+	  it's sign_extend vs zero_extend.  */
+       && (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type)
+	   || (TYPE_UNSIGNED (TREE_TYPE (@2))
+	       == TYPE_UNSIGNED (TREE_TYPE (@3))))
        && single_use (@4)
        && single_use (@5))))
diff --git a/gcc/testsuite/gcc.target/i386/pr104551.c b/gcc/testsuite/gcc.target/i386/pr104551.c
new file mode 100644
index 00000000000..6300f25c0d5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr104551.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -mavx2" } */
+/* { dg-require-effective-target avx2 } */
+
+unsigned int
+__attribute__((noipa))
+test(unsigned int a, unsigned char p[16]) {
+  unsigned int res = 0;
+  for (unsigned b = 0; b < a; b += 1)
+    res = p[b] ? p[b] : (char) b;
+  return res;
+}
+
+int main ()
+{
+  unsigned int a = 16U;
+  unsigned char p[16];
+  for (int i = 0; i != 16; i++)
+    p[i] = (unsigned char)128;
+  unsigned int res = test (a, p);
+  if (res != 128)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
index a8f96d59643..217bdfd7045 100644
--- a/gcc/tree-vect-patterns.cc
+++ b/gcc/tree-vect-patterns.cc
@@ -929,8 +929,10 @@ vect_reassociating_reduction_p (vec_info *vinfo,
    with conditions:
    1) @1, @2, c, d, a, b are all integral type.
    2) There's single_use for both @1 and @2.
-   3) a, c and d have same precision.
+   3) a, c have same precision.
    4) c and @1 have different precision.
+   5) c, d are the same type or they can differ in sign when convert is
+   truncation.
 
    record a and c and d and @3.  */
 
@@ -952,7 +954,7 @@ extern bool gimple_cond_expr_convert_p (tree, tree*, tree (*)(tree));
    TYPE_PRECISION (TYPE_E) != TYPE_PRECISION (TYPE_CD);
    TYPE_PRECISION (TYPE_AB) == TYPE_PRECISION (TYPE_CD);
    single_use of op_true and op_false.
-   TYPE_AB could differ in sign.
+   TYPE_AB could differ in sign when (TYPE_E) A is a truncation.
 
    Input:
 
-- 
2.18.1


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

* Re: [PATCH V2] Restrict the two sources of vect_recog_cond_expr_convert_pattern to be of the same type when convert is extension.
  2022-02-17  5:31             ` [PATCH V2] " liuhongt
@ 2022-02-17  9:48               ` Richard Biener
  0 siblings, 0 replies; 9+ messages in thread
From: Richard Biener @ 2022-02-17  9:48 UTC (permalink / raw)
  To: liuhongt; +Cc: GCC Patches, Jakub Jelinek

On Thu, Feb 17, 2022 at 6:32 AM liuhongt via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> > I find this quite unreadable, it looks like if @2 and @3 are treated
> > differently.  I think keeping the old 3 lines and just adding
> >       && (TYPE_PRECISION (TREE_TYPE (@0)) >= TYPE_PRECISION (type)
> >           || (TYPE_UNSIGNED (TREE_TYPE (@2))
> >               == TYPE_UNSIGNED (TREE_TYPE (@3))))
> > after it ideally with a comment why would be better.
> Update patch.

OK.

Thanks,
Richard.

> gcc/ChangeLog:
>
>         PR tree-optimization/104551
>         PR tree-optimization/103771
>         * match.pd (cond_expr_convert_p): Add types_match check when
>         convert is extension.
>         * tree-vect-patterns.cc
>         (gimple_cond_expr_convert_p): Adjust comments.
>         (vect_recog_cond_expr_convert_pattern): Ditto.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/i386/pr104551.c: New test.
> ---
>  gcc/match.pd                             |  6 ++++++
>  gcc/testsuite/gcc.target/i386/pr104551.c | 24 ++++++++++++++++++++++++
>  gcc/tree-vect-patterns.cc                |  6 ++++--
>  3 files changed, 34 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr104551.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 05a10ab6bfd..8b6f22f1065 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -7698,5 +7698,11 @@ and,
>           == TYPE_PRECISION (TREE_TYPE (@2))
>         && TYPE_PRECISION (TREE_TYPE (@0))
>           == TYPE_PRECISION (TREE_TYPE (@3))
> +       /* For vect_recog_cond_expr_convert_pattern, @2 and @3 can differ in
> +         signess when convert is truncation, but not ok for extension since
> +         it's sign_extend vs zero_extend.  */
> +       && (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type)
> +          || (TYPE_UNSIGNED (TREE_TYPE (@2))
> +              == TYPE_UNSIGNED (TREE_TYPE (@3))))
>         && single_use (@4)
>         && single_use (@5))))
> diff --git a/gcc/testsuite/gcc.target/i386/pr104551.c b/gcc/testsuite/gcc.target/i386/pr104551.c
> new file mode 100644
> index 00000000000..6300f25c0d5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr104551.c
> @@ -0,0 +1,24 @@
> +/* { dg-do run } */
> +/* { dg-options "-O3 -mavx2" } */
> +/* { dg-require-effective-target avx2 } */
> +
> +unsigned int
> +__attribute__((noipa))
> +test(unsigned int a, unsigned char p[16]) {
> +  unsigned int res = 0;
> +  for (unsigned b = 0; b < a; b += 1)
> +    res = p[b] ? p[b] : (char) b;
> +  return res;
> +}
> +
> +int main ()
> +{
> +  unsigned int a = 16U;
> +  unsigned char p[16];
> +  for (int i = 0; i != 16; i++)
> +    p[i] = (unsigned char)128;
> +  unsigned int res = test (a, p);
> +  if (res != 128)
> +    __builtin_abort ();
> +  return 0;
> +}
> diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
> index a8f96d59643..217bdfd7045 100644
> --- a/gcc/tree-vect-patterns.cc
> +++ b/gcc/tree-vect-patterns.cc
> @@ -929,8 +929,10 @@ vect_reassociating_reduction_p (vec_info *vinfo,
>     with conditions:
>     1) @1, @2, c, d, a, b are all integral type.
>     2) There's single_use for both @1 and @2.
> -   3) a, c and d have same precision.
> +   3) a, c have same precision.
>     4) c and @1 have different precision.
> +   5) c, d are the same type or they can differ in sign when convert is
> +   truncation.
>
>     record a and c and d and @3.  */
>
> @@ -952,7 +954,7 @@ extern bool gimple_cond_expr_convert_p (tree, tree*, tree (*)(tree));
>     TYPE_PRECISION (TYPE_E) != TYPE_PRECISION (TYPE_CD);
>     TYPE_PRECISION (TYPE_AB) == TYPE_PRECISION (TYPE_CD);
>     single_use of op_true and op_false.
> -   TYPE_AB could differ in sign.
> +   TYPE_AB could differ in sign when (TYPE_E) A is a truncation.
>
>     Input:
>
> --
> 2.18.1
>

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

end of thread, other threads:[~2022-02-17  9:48 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-24 13:01 [PATCH] [vect] Add vect_recog_cond_expr_convert_pattern liuhongt
2022-02-08  8:48 ` Richard Biener
2022-02-10  6:59   ` liuhongt
2022-02-11 12:29     ` Richard Biener
2022-02-16  9:03       ` [PATCH] Restrict the two sources of vect_recog_cond_expr_convert_pattern to be of the same type when convert is extension liuhongt
2022-02-16 14:15         ` Jakub Jelinek
2022-02-17  1:30           ` Hongtao Liu
2022-02-17  5:31             ` [PATCH V2] " liuhongt
2022-02-17  9:48               ` Richard Biener

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).