This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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])


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

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

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]