------- 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