This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR optimization/15112
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sat, 1 May 2004 15:33:56 +0200
- Subject: [PATCH] Fix PR optimization/15112
Hi Richard,
Do you remember the problem we ran into on the 3.3 branch with reload
generating stores to read-only memory? The problem was that a REG_EQUAL
note attached to a pseudo and referencing a MEM/u was promoted by
local-alloc to a REG_EQUIV note; then, as the pseudo didn't get a hard get,
it was replaced by the MEM/u as the destination of the store.
My patch prevented reload from recording MEM/u as equivalent memory locations
for pseudos. It was eventually applied to the 3.3 and 3.3 RHL branches.
Now we have exactly the same problem on the 3.4 branch, with roughly the same
testcase (files attached, with -O3 -funroll-loops). Reload generates this:
(insn:HI 98 68 86 1 (set (mem/u/f:SI (symbol_ref:SI ("q") [flags 0x40]
<var_decl 0x4021b360 q>) [2 q+0 S4 A32])
(reg:SI 2 cx [orig:68 q ] [68])) 36 {*movsi_1} (nil)
(expr_list:REG_EQUIV (mem/u/f:SI (symbol_ref:SI ("q") [flags 0x40]
<var_decl 0x4021b360 q>) [2 q+0 S4 A32])
(nil)))
for
extern const int q;
Again this comes from:
(insn:HI 98 68 86 1 (set (reg/v:SI 59 [ j ])
(reg:SI 68 [ q ])) 36 {*movsi_1} (nil)
(expr_list:REG_EQUIV (mem/u/f:SI (symbol_ref:SI ("q") [flags 0x40]
<var_decl 0x4021b360 q>) [2 q+0 S4 A32])
(nil)))
and (reg 59) didn't get a hard reg according to the logfile.
Should we put the patch on that branch too (bootstrapped/regtested on
i586-redhat-linux-gnu without a hitch) or try something more sophisticated?
Thanks in advance.
--
Eric Botcazou
const int q = 0;
void c(void);
double b(int);
int main()
{
c();
}
double b( int i )
{
return 1.;
}
extern const int q;
struct {
double a[2];
} h;
double b(int);
void c(void)
{
int i, j;
for( i=0; i < 2; i++ )
for( j=q; j < i; j++ )
h.a[i] += b(j);
h.a[q] = 0.;
return;
}
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.419.4.4
diff -u -p -r1.419.4.4 reload1.c
--- reload1.c 22 Apr 2004 21:27:05 -0000 1.419.4.4
+++ reload1.c 30 Apr 2004 06:02:59 -0000
@@ -747,8 +747,18 @@ reload (rtx first, int global)
that is not a legitimate memory operand. As later
stages of reload assume that all addresses found
in the reg_equiv_* arrays were originally legitimate,
- we ignore such REG_EQUIV notes. */
- if (memory_operand (x, VOIDmode))
+ we ignore such REG_EQUIV notes.
+
+ It also can happen that a REG_EQUIV note contains a MEM
+ that carries the /u flag, for example when GCSE turns
+ the load of a constant into a move from a pseudo that
+ already contains the constant and attaches a REG_EQUAL
+ note to the insn, which is later promoted to REQ_EQUIV
+ by local-alloc. If the destination pseudo happens not
+ to be assigned to a hard reg, it will be replaced by
+ the MEM as the destination of the move, thus generating
+ a store to a possibly read-only memory location. */
+ if (memory_operand (x, VOIDmode) && ! RTX_UNCHANGING_P (x))
{
/* Always unshare the equivalence, so we can
substitute into this insn without touching the