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