diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 880dff8ded647f45eee2b5ec69140c7d4d10d632..9c3c9e2d4f8870c807587b04a4c7c58702b53ab0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-01-31 Richard Biener <rguenther@suse.de> + + PR tree-optimization/56157 + * tree-vect-slp.c (vect_get_slp_defs): More thoroughly try to + match up operand with SLP child. + 2013-01-31 Jason Merrill <jason@redhat.com> PR c++/54410 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2632cd06d07cdc0139277f1b8ea5ec2ceb624248..7a8baa6e9051f9133ce94cd50b0d60400f2becd2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-01-31 Richard Biener <rguenther@suse.de> + + PR tree-optimization/56157 + * gcc.dg/torture/pr56157.c: New testcase. + 2013-01-30 Richard Biener <rguenther@suse.de> PR tree-optimization/56150 diff --git a/gcc/testsuite/gcc.dg/torture/pr56157.c b/gcc/testsuite/gcc.dg/torture/pr56157.c new file mode 100644 index 0000000000000000000000000000000000000000..796e3235c299d7d990ef94076783f52ba2257caa --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr56157.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-ftree-vectorize" } */ + +struct Pixel { + unsigned short r; + unsigned short g; + unsigned short b; + unsigned short a; +}; + +void fn(unsigned char * __restrict dst, const unsigned char * __restrict src) +{ + unsigned x; + for(x = 0; x < 1024; x += 1) + { + struct Pixel pixel; + pixel.r = (unsigned short)(((unsigned)src[0]) * 0xffff / 0xff); + pixel.g = (unsigned short)(((unsigned)src[1]) * 0xffff / 0xff); + pixel.b = (unsigned short)(((unsigned)src[2]) * 0xffff / 0xff); + pixel.a = (unsigned short)(((unsigned)src[3]) * 0xffff / 0xff); + __builtin_memcpy(dst, &pixel, sizeof pixel); + src += 4; + dst += 8; + } +} diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 941661e0edc18e42793c79f15970b0e62fbb4b21..36f81299d5c5ace6b243ccd40d00d3feff8d8983 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -2616,13 +2616,13 @@ void vect_get_slp_defs (vec<tree> ops, slp_tree slp_node, vec<slp_void_p> *vec_oprnds, int reduc_index) { - gimple first_stmt, first_def; + gimple first_stmt; int number_of_vects = 0, i; unsigned int child_index = 0; HOST_WIDE_INT lhs_size_unit, rhs_size_unit; slp_tree child = NULL; vec<tree> *vec_defs; - tree oprnd, def_lhs; + tree oprnd; bool vectorized_defs; first_stmt = SLP_TREE_SCALAR_STMTS (slp_node)[0]; @@ -2638,29 +2638,22 @@ vect_get_slp_defs (vec<tree> ops, slp_tree slp_node, if (SLP_TREE_CHILDREN (slp_node).length () > child_index) { child = (slp_tree) SLP_TREE_CHILDREN (slp_node)[child_index]; - first_def = SLP_TREE_SCALAR_STMTS (child)[0]; - - /* In the end of a pattern sequence we have a use of the original stmt, - so we need to compare OPRND with the original def. */ - if (is_pattern_stmt_p (vinfo_for_stmt (first_def)) - && !STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (first_stmt)) - && !is_pattern_stmt_p (vinfo_for_stmt (first_stmt))) - first_def = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (first_def)); - if (is_gimple_call (first_def)) - def_lhs = gimple_call_lhs (first_def); - else - def_lhs = gimple_assign_lhs (first_def); + /* We have to check both pattern and original def, if available. */ + gimple first_def = SLP_TREE_SCALAR_STMTS (child)[0]; + gimple related = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (first_def)); - if (operand_equal_p (oprnd, def_lhs, 0)) - { - /* The number of vector defs is determined by the number of - vector statements in the node from which we get those + if (operand_equal_p (oprnd, gimple_get_lhs (first_def), 0) + || (related + && operand_equal_p (oprnd, gimple_get_lhs (related), 0))) + { + /* The number of vector defs is determined by the number of + vector statements in the node from which we get those statements. */ - number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (child); - vectorized_defs = true; + number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (child); + vectorized_defs = true; child_index++; - } + } } if (!vectorized_defs)