http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49103
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-05-23 07:35:48 UTC --- Ugh, the problem is that first cunrolli unrolls the loop, so we get among other things parm.9 initialized for printing fgrades_35, then _gfortran_transfer_array_write from parm.9, then parm.11 initialized for printing fbasegrades_19, then _gfortran_transfer_array_write from parm.11, then again parm.9 initialized to the same values again, _gfortran_transfer_array_write from it, parm.11 to the same values and _gfortran_transfer_array_write from it. Additionally, _gfortran_transfer_array_write uses ".wr" "fn spec" attribute. Next comes fre (2nd), which sees the ".wr" fn spec and removes the second identical initialization of parm.9 and parm.11, so parm.9 is no longer live in two separate ranges, but also across the parm.11 initialization and _gfortran_transfer_array_write call from it. And during expansion, we figure out that parm.9 and parm.11 are in different, non-overlapping blocks and thus decide to share the stack slot for both. Appart from the ".wr" "fn spec" attribute I think there is nothing fortran specific and with struct S { largish struct }; for (int i = 0; i < 2; i++) { { struct S a; initialize a; use a; } { struct S b; initialize b; use b; } } we could achieve similar effect (though, if e.g. use is a pure function, the second call would be deleted). So, I'm not convinced reverting my patch is the right fix. Not sure how to allow expansion to notice that unrolling made it impossible to share the stack slots though. Ideas?