From: liuhongt Date: Wed, 16 Feb 2022 04:15:18 +0000 (+0800) Subject: Restrict the two sources of vect_recog_cond_expr_convert_pattern to be of the same... X-Git-Tag: basepoints/gcc-13~1037 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=754dce903ca28c4c2f2bc8614a8de5e631655f2e;p=thirdparty%2Fgcc.git Restrict the two sources of vect_recog_cond_expr_convert_pattern to be of the same type when convert is extension. It's not equal to transform (cond (cmp @1 @2) (convert@3 @4) (convert@5 @6)) to (convert (cmp @1 @2) (convert)@4 @6) when(convert@3 @4) is extension because it's zero_extend vs sign_extend. 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. --- diff --git a/gcc/match.pd b/gcc/match.pd index 05a10ab6bfd1..8b6f22f10658 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 000000000000..6300f25c0d50 --- /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 a8f96d59643d..217bdfd7045a 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: