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.
This commit is contained in:
parent
1c2b44b523
commit
754dce903c
|
@ -7698,5 +7698,11 @@ and,
|
||||||
== TYPE_PRECISION (TREE_TYPE (@2))
|
== TYPE_PRECISION (TREE_TYPE (@2))
|
||||||
&& TYPE_PRECISION (TREE_TYPE (@0))
|
&& TYPE_PRECISION (TREE_TYPE (@0))
|
||||||
== TYPE_PRECISION (TREE_TYPE (@3))
|
== 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 (@4)
|
||||||
&& single_use (@5))))
|
&& single_use (@5))))
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -929,8 +929,10 @@ vect_reassociating_reduction_p (vec_info *vinfo,
|
||||||
with conditions:
|
with conditions:
|
||||||
1) @1, @2, c, d, a, b are all integral type.
|
1) @1, @2, c, d, a, b are all integral type.
|
||||||
2) There's single_use for both @1 and @2.
|
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.
|
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. */
|
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_E) != TYPE_PRECISION (TYPE_CD);
|
||||||
TYPE_PRECISION (TYPE_AB) == TYPE_PRECISION (TYPE_CD);
|
TYPE_PRECISION (TYPE_AB) == TYPE_PRECISION (TYPE_CD);
|
||||||
single_use of op_true and op_false.
|
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:
|
Input:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue