This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR optimization/12544
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Mark Mitchell <mark at codesourcery dot com>
- Date: Sat, 11 Oct 2003 19:05:21 +0200
- Subject: [PATCH] Fix PR optimization/12544
Hi,
This is a regression from GCC 3.2.3 present on the 3.3 branch and mainline
that shows up on SPARC (and more generally on targets that pass structures
by invisible references), caused by my patch that has instructed the
compiler to set the DECL_NONLOCAL flag on variables used by nested functions
during the parsing of their parent, instead of during the RTL generation of
the child functions.
It turns out that put_var_into_stack implicitly thinks that DECL_NONLOCAL can
only be seen from within nested functions, which is of course not true
anymore. More precisely, it applies a first transformation reserved to
special DECL_NONLOCAL decls then a second one reserved to non-DECL_NONLOCAL
decls, because it doesn't test the DECL_NONLOCAL flag in the second case. So
we end up putting a DECL_NONLOCAL argument in an ADDRESSOF with a bogus mode
and ICE when attempting to generate a SImode to BLKmode move.
Bootstrapped/regtested on sparc-sun-solaris2.8 (3.3 branch except Ada). Ok
for mainline and 3.3 branch?
Mark, I'm not sure you want this patch for 3.3.2 so I'm prepared to wait
until the branch reopens (if it ever reopens).
2003-10-11 Eric Botcazou <ebotcazou@libertysurf.fr>
PR optimization/12544
* function.c (put_var_into_stack): Don't generate
ADDRESSOFs for DECL_NONLOCAL decls.
2003-10-11 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.c-torture/compile/20031011-1.c: New test.
--
Eric Botcazou
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.389.2.10
diff -u -p -r1.389.2.10 function.c
--- function.c 10 Apr 2003 22:26:04 -0000 1.389.2.10
+++ function.c 11 Oct 2003 12:13:15 -0000
@@ -1373,8 +1373,9 @@ put_var_into_stack (decl, rescan)
if (function->decl == context)
break;
- /* If this is a variable-size object with a pseudo to address it,
- put that pseudo into the stack, if the var is nonlocal. */
+ /* If this is a variable-sized object or a structure passed by invisible
+ reference, with a pseudo to address it, put that pseudo into the stack
+ if the var is non-local. */
if (TREE_CODE (decl) != SAVE_EXPR && DECL_NONLOCAL (decl)
&& GET_CODE (reg) == MEM
&& GET_CODE (XEXP (reg, 0)) == REG
@@ -1384,8 +1385,12 @@ put_var_into_stack (decl, rescan)
decl_mode = promoted_mode = GET_MODE (reg);
}
+ /* If this variable lives in the current function and we don't need to put it
+ in the stack for the sake of setjmp or the non-locality, try to keep it in
+ a register until we know we actually need the address. */
can_use_addressof
= (function == 0
+ && ! (TREE_CODE (decl) != SAVE_EXPR && DECL_NONLOCAL (decl))
&& optimize > 0
/* FIXME make it work for promoted modes too */
&& decl_mode == promoted_mode
@@ -1404,9 +1409,6 @@ put_var_into_stack (decl, rescan)
if (GET_CODE (reg) == REG)
{
- /* If this variable lives in the current function and we don't need
- to put things in the stack for the sake of setjmp, try to keep it
- in a register until we know we actually need the address. */
if (can_use_addressof)
gen_mem_addressof (reg, decl, rescan);
else
/* PR optimization/12544 */
/* Origin: Tony Hosking <hosking@cs.purdue.edu> */
/* Verify that non-local structures passed by reference
are correctly put in the stack. */
typedef struct {
int a;
int f;
} A;
A *b;
void x (A a) {
void y () {
a.a = 0;
}
b = &a;
y();
}