diff --git a/gcc/testsuite/gcc.dg/torture/pr95761.c b/gcc/testsuite/gcc.dg/torture/pr95761.c new file mode 100644 index 00000000000..65ee0fc1c11 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr95761.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ + +typedef int a[10]; +typedef struct { + a b; + a c; + a d; + a e; +} f; +f g; +int *j; +void k() { + for (;;) { + a l; + j[0] = g.b[0]; + int *h = g.d; + int i = 0; + for (; i < 10; i++) + h[i] = l[0] - g.e[0]; + h = g.e; + i = 0; + for (; i < 10; i++) + h[i] = l[1] + g.e[i]; + } +} diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 98b5542806f..84b97270cd1 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -4199,7 +4199,6 @@ vect_schedule_slp_instance (vec_info *vinfo, { /* Or if we do not have 1:1 matching scalar stmts emit after the children vectorized defs. */ - gimple *last_in_child; gimple *last_stmt = NULL; FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child) /* ??? With only external defs the following breaks. Note @@ -4208,11 +4207,15 @@ vect_schedule_slp_instance (vec_info *vinfo, if (SLP_TREE_DEF_TYPE (child) == vect_internal_def) { /* We are emitting all vectorized stmts in the same place and - the last one is the last. */ - last_in_child = SLP_TREE_VEC_STMTS (child).last (); - if (!last_stmt - || vect_stmt_dominates_stmt_p (last_stmt, last_in_child)) - last_stmt = last_in_child; + the last one is the last. + ??? Unless we have a load permutation applied and that + figures to re-use an earlier generated load. */ + unsigned j; + gimple *vstmt; + FOR_EACH_VEC_ELT (SLP_TREE_VEC_STMTS (child), j, vstmt) + if (!last_stmt + || vect_stmt_dominates_stmt_p (last_stmt, vstmt)) + last_stmt = vstmt; } if (is_a (last_stmt)) si = gsi_after_labels (gimple_bb (last_stmt));