------- Comment #4 from jakub at gcc dot gnu dot org 2008-04-02 16:20 ------- Heh, I was testing with -m32 and -m64 on 4.3 branch (but that was --enable-checking=release default) and on the trunk just -m64. Can reproduce now.
This seems to be NRV that is creating non-GIMPLE by replacing GIMPLE regs with <result> which needs to live in memory. The following patch cures this, though I'm not sure if it can actually pessimize code: --- tree-nrv.c.jj 2008-03-19 14:18:00.000000000 +0100 +++ tree-nrv.c 2008-04-02 18:11:14.000000000 +0200 @@ -1,5 +1,5 @@ /* Language independent return value optimizations - Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. This file is part of GCC. @@ -115,6 +115,11 @@ tree_nrv (void) if (!aggregate_value_p (result, current_function_decl)) return 0; + /* If a GIMPLE type is returned in memory, finalize_nrv_r might create + non-GIMPLE. */ + if (is_gimple_reg_type (result_type)) + return 0; + /* Look through each block for assignments to the RESULT_DECL. */ FOR_EACH_BB (bb) { The idea is that if found var isn't really an aggregate, but gimple reg, then 1) nvr might create non-GIMPLE as say x = x + 32; can be valid, while <result> = <result> + 32; where <result> is aggregate_value_p and thus needs_to_live_in_memory is true for it is invalid GIMPLE (without -fmudflap just no pass verified that) 2) the replacement might tie hands of the RTL passes - without the nrv replacement it works with pseudos, but with the nrv replacement it suddenly needs to be MEM in all the operations on it. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35739