http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57517
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |rakdver at gcc dot gnu.org --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- We also fail to sink the loads (because appearantly we don't want to do that, eh), which in the end causes this havoc (not-always-executed combination). C testcase: int x[1024], y[1024], z[1024], w[1024]; void foo (void) { int i; for (i = 1; i < 1024; ++i) { int a = x[i]; int b = y[i]; int c = x[i-1]; int d = y[i-1]; if (w[i]) z[i] = (a + b) + (c + d); } } Fixed by for example the simple Index: gcc/tree-predcom.c =================================================================== --- gcc/tree-predcom.c (revision 204948) +++ gcc/tree-predcom.c (working copy) @@ -2068,7 +2068,11 @@ combinable_refs_p (dref r1, dref r2, stmt = find_common_use_stmt (&name1, &name2); - if (!stmt) + if (!stmt + /* A simple post-dominance check - make sure the combination + is executed under the same condition as the references. */ + || (gimple_bb (stmt) != gimple_bb (r1->stmt) + && gimple_bb (stmt) != gimple_bb (r2->stmt))) return false; acode = gimple_assign_rhs_code (stmt); Zdenek?