https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81365
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The optimization and thus the bug too has been introduced in r235208, i.e. PR70171. The check Andrew mentions has been added in r236079, i.e. PR71039. But it actually does something completely different than the check we need here, it makes sure that any SSA_NAMEs used in the lhs that we move earlier is available there already. What we need here is something different. We already have: /* Check if we can move the loads. The def stmt of the virtual use needs to be in a different basic block dominating bb. When the def is an edge-inserted one we know it dominates us. */ vuse = gimple_vuse (use_stmt); def_stmt = SSA_NAME_DEF_STMT (vuse); if (!SSA_NAME_IS_DEFAULT_DEF (vuse) && (gimple_bb (def_stmt) == bb || (gimple_bb (def_stmt) && !dominated_by_p (CDI_DOMINATORS, bb, gimple_bb (def_stmt))))) goto next; which makes sure we don't miscompile int h(int k, int i1, int j1) { int *f1; if(k) f1 = &i1; else f1 = &j1; i1 = 7; return *f1; } where the use_stmt has an earlier store that might modify it. That is sufficient for the reg type case, but for the aggregate, where we actually move the aggregate store earlier - onto the edges - we also have to ensure that either there no memory loads between the PHI and use_stmt, or that the can't alias the lhs.