See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60896 for bug report.
The cause of PR60896 is that those statements in PATTERN_DEF_SEQ in pre-recognized widen-mult pattern are not forwarded to later recognized dot-product pattern. Another issue is that the def types of statements in PATTERN_DEF_SEQ are assigned with the def type of the pattern statement. This is incorrect for reduction pattern statement, in which case all statements in PATTERN_DEF_SEQ will all be vect_reduction_def, and none of them will be vectorized later. The def type of statement in PATTERN_DEF_SEQ should always be vect_internal_def. The patch is attached. Bootstrapped and tested on a x86_64 machine. OK for trunk? thanks, Cong
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 117cdd0..0af5e16 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2014-04-23 Cong Hou <co...@google.com> + + PR tree-optimization/60896 + * tree-vect-patterns.c (vect_recog_dot_prod_pattern): Pick up + all statements in PATTERN_DEF_SEQ in recognized widen-mult pattern. + (vect_mark_pattern_stmts): Set the def type of all statements in + PATTERN_DEF_SEQ as vect_internal_def. + 2014-04-23 David Malcolm <dmalc...@redhat.com> * is-a.h: Update comments to reflect the following changes to the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 62b07f4..55bc842 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-04-23 Cong Hou <co...@google.com> + + PR tree-optimization/60896 + * g++.dg/vect/pr60896.cc: New test. + 2014-04-23 Jeff Law <l...@redhat.com> PR tree-optimization/60902 diff --git a/gcc/testsuite/g++.dg/vect/pr60896.cc b/gcc/testsuite/g++.dg/vect/pr60896.cc new file mode 100644 index 0000000..c6ce68b --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/pr60896.cc @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +struct A +{ + int m_fn1 (); + short *m_fn2 (); +}; + +struct B +{ + void *fC; +}; + +int a, b; +unsigned char i; +void fn1 (unsigned char *p1, A &p2) +{ + int c = p2.m_fn1 (); + for (int d = 0; c; d++) + { + short *e = p2.m_fn2 (); + unsigned char *f = &p1[0]; + for (int g = 0; g < a; g++) + { + int h = e[0]; + b += h * f[g]; + } + } +} + +void fn2 (A &p1, A &p2, B &p3) +{ + int j = p2.m_fn1 (); + for (int k = 0; j; k++) + if (0) + ; + else + fn1 (&i, p1); + if (p3.fC) + ; + else + ; +} diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 5daaf24..365cf01 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -392,6 +392,8 @@ vect_recog_dot_prod_pattern (vec<gimple> *stmts, tree *type_in, gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_internal_def); oprnd00 = gimple_assign_rhs1 (stmt); oprnd01 = gimple_assign_rhs2 (stmt); + STMT_VINFO_PATTERN_DEF_SEQ (vinfo_for_stmt (last_stmt)) + = STMT_VINFO_PATTERN_DEF_SEQ (stmt_vinfo); } else { @@ -3065,8 +3067,7 @@ vect_mark_pattern_stmts (gimple orig_stmt, gimple pattern_stmt, } gimple_set_bb (def_stmt, gimple_bb (orig_stmt)); STMT_VINFO_RELATED_STMT (def_stmt_info) = orig_stmt; - STMT_VINFO_DEF_TYPE (def_stmt_info) - = STMT_VINFO_DEF_TYPE (orig_stmt_info); + STMT_VINFO_DEF_TYPE (def_stmt_info) = vect_internal_def; if (STMT_VINFO_VECTYPE (def_stmt_info) == NULL_TREE) STMT_VINFO_VECTYPE (def_stmt_info) = pattern_vectype; }