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


This is a regression from GCC 3.2.3 on SPARC64, present on the 3.3 branch.

The assignments to the bit-fields in the constructor of

struct A
  enum Type {P, U, S};

  const size_t mSize : 8*sizeof(size_t) - 3;
  Type mType : 2;

use the same memory address, but the first MEM is marked as unchanging while 
the second MEM is not. From 00.rtl:

(insn 23 22 24 (nil) (set (mem/s/u/j:DI (reg/v/f:DI 110) [0 S8 A64])
        (reg:DI 112)) -1 (nil)

(insn 29 28 31 (nil) (set (mem/s/j:DI (reg/v/f:DI 110) [0 S8 A64])
        (reg:DI 114)) -1 (nil)

So there are not detected as aliasing and are swapped by the scheduler, which 
produces wrong code since the first assignment doesn't contain the value for 
the second bit-field.

The problem is hidden on mainline by

2003-09-12  Roger Sayle  <>

	PR optimization/8967
	* alias.c (write_dependence_p): Modify to take an additional constp
	argument that controls whether the UNCHANGING_RTX_P flags are used.
	(anti_dependence, output_dependence): Adjust write_dependence_p
	callers to pass this additional argument, to return the same result.
	(unchanging_anti_dependence): New variant of anti_dependence that
	ignores the UNCHANGING_RTX_P property on memory references.
	* rtl.h (unchaning_anti_dependence): Prototype here.
	* flow.c (init_propagate_block): Place fake constant mem writes on
	the mem_set_list so that dead writes to const variables are deleted.
	(insn_dead_p): Change anti_dependence to unchanging_anti_dependence.
	(mark_used_regs): Likewise.

because flow.c is able to delete the first assignment as dead. However, I 
think that the semantics of UNCHANGING_RTX_P is still violated by the RTL 

The proposed fix is to not put the UNCHANGING_RTX_P flag on a MEM which is 
not addressable, because a non-unchanging object might be referenced by the 
same MEM.

Bootstrapped/regtested on i586-redhat-linux-gnu (3.3 branch except Ada). Ok 
for mainline and 3.3 branch?

2003-11-12  Eric Botcazou  <>

        PR optimization/12926
	* expr.c (expand_assignment) [COMPONENT_REF]: Don't put
	the UNCHANGING_RTX_P flag on memory references to read-only
	components that are not addressable. 

2003-11-12  Eric Botcazou  <>

        * g++.dg/opt/const3.C: New test.

Eric Botcazou
Index: expr.c
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.498.2.21
diff -u -p -r1.498.2.21 expr.c
--- expr.c	6 Sep 2003 08:06:00 -0000	1.498.2.21
+++ expr.c	11 Nov 2003 12:49:10 -0000
@@ -4128,7 +4128,11 @@ expand_assignment (to, from, want_value,
       if (TREE_CODE (to) == COMPONENT_REF
+	  /* We can't assert that a MEM won't be set more than once
+	     if the component is not addressable because another
+	     non-addressable component may be referenced by the same MEM.  */
+	  && ! (GET_CODE (to_rtx) == MEM && ! can_address_p (to)))
 	  if (to_rtx == orig_to_rtx)
 	    to_rtx = copy_rtx (to_rtx);
// PR optimization/12926
// This failed on SPARC64 because the assignments to the bit-fields
// were wrongly swapped in the constructor.

// { dg-do run }
// { dg-options "-O2" }

extern void abort(void);

typedef __SIZE_TYPE__ size_t;

void *my_out;

struct A
  enum Type {P, U, S};

  int foo1(void *, const char *);
  int foo2(int, const Type);

  A (const size_t size, const Type type): mSize(size), mType(type)
      foo2(foo1(my_out, "type = "), type);
      foo2(foo1(my_out, "mType = "), mType);

  const size_t mSize : 8*sizeof(size_t) - 3;
  Type mType : 2;

int i;

int A::foo1(void *ios, const char *str) { }
int A::foo2(int v, const Type t) { i=0; }

int main()
  A testa(2, A::S);

  if (testa.mType != A::S)

  return 0;

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