This fixes the bug Jakub noticed - we fail to distribute all stores and just drop them (oops).
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2013-11-15 Richard Biener <rguent...@suse.de> * tree-loop-distribution.c (tree_loop_distribution): Make sure to distribute all stores. * gcc.dg/torture/20131115-1.c: New testcase. Index: gcc/tree-loop-distribution.c =================================================================== --- gcc/tree-loop-distribution.c (revision 204787) +++ gcc/tree-loop-distribution.c (working copy) @@ -1723,8 +1723,7 @@ tree_loop_distribution (void) if (stmt_has_scalar_dependences_outside_loop (loop, stmt)) ; /* Otherwise only distribute stores for now. */ - else if (!gimple_assign_single_p (stmt) - || is_gimple_reg (gimple_assign_lhs (stmt))) + else if (!gimple_vdef (stmt)) continue; work_list.safe_push (stmt); Index: gcc/testsuite/gcc.dg/torture/20131115-1.c =================================================================== --- gcc/testsuite/gcc.dg/torture/20131115-1.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/20131115-1.c (working copy) @@ -0,0 +1,38 @@ +/* { dg-do run } */ + +struct S { int i; }; +__attribute__((const, noinline, noclone)) +struct S foo (int x) +{ + struct S s; + s.i = x; + return s; +} + +int a[2048], b[2048], c[2048], d[2048]; +struct S e[2048]; + +__attribute__((noinline, noclone)) void +bar (void) +{ + int i; + for (i = 0; i < 1024; i++) + { + e[i] = foo (i); + a[i+2] = a[i] + a[i+1]; + b[10] = b[10] + i; + c[i] = c[2047 - i]; + d[i] = d[i + 1]; + } +} + +int +main () +{ + int i; + bar (); + for (i = 0; i < 1024; i++) + if (e[i].i != i) + __builtin_abort (); + return 0; +}