This is the mail archive of the gcc-patches@gcc.gnu.org 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 another problem with RTX_UNCHANGING_P


Hi!

The following testcase is miscompiled on both gcc-3_3-branch,
gcc-3_3-rhl-branch and TRUNK (for trunk with the obvious s/cpu/tune/
change).  The problem is that GCC initializes the constructor with:
(insn 12 10 13 0 (parallel [
            (set (reg/f:SI 60)
                (plus:SI (reg/f:SI %eframe)
                    (const_int -32 [0xffffffe0])))
            (clobber (reg:CC %eflags))
        ]) 138 {*addsi_1} (nil)
    (nil))

(insn 13 12 14 0 (set (reg:SI %edirflag)
        (const_int 0 [0x0])) 440 {cld} (nil)
    (nil))
...
(insn 17 15 18 0 (parallel [
            (set (reg:SI 63)
                (const_int 0 [0x0]))
            (set (reg/f:SI 60)
                (plus:SI (ashift:SI (reg:SI 62)
                        (const_int 2 [0x2]))
                    (reg/f:SI 60)))
            (set (mem:BLK (reg/f:SI 60) [0 A8])
                (const_int 0 [0x0]))
            (use (reg:SI 61))
            (use (reg:SI 62))
            (use (reg:SI %edirflag))
        ]) 449 {rep_stossi} (nil)
    (nil))

(insn 18 17 29 0 (set (mem/s/u:SI (plus:SI (reg/f:SI %eframe)
                (const_int -24 [0xffffffe8])) [6 y+8 S4 A64])
        (reg/v/f:SI 59 [ x ])) 36 {*movsi_1} (nil)
    (nil))

(note /u in the last insn).  This violates RTX_UNCHANGING_P, since
the memory at eframe-24 is written more than once and sched2 happily
moves insn 18 before insn 17.
Ok to commit (TRUNK, gcc-3_3-branch)?

2003-12-02  Jakub Jelinek  <jakub@redhat.com>

	* expr.c (store_constructor): Only set RTX_UNCHANGING_P for
	read-only field if cleared is 0.

	* gcc.dg/20031202-1.c: New test.

--- gcc/expr.c.jj	2003-12-02 17:51:57.000000000 +0100
+++ gcc/expr.c	2003-12-02 18:09:59.000000000 +0100
@@ -4936,7 +4936,10 @@ store_constructor (exp, target, cleared,
 				       highest_pow2_factor (offset));
 	    }
 
-	  if (TREE_READONLY (field))
+	  /* If the constructor has been cleared, setting RTX_UNCHANGING_P
+	     on the MEM might lead to scheduling the clearing after the
+	     store.  */
+	  if (TREE_READONLY (field) && !cleared)
 	    {
 	      if (GET_CODE (to_rtx) == MEM)
 		to_rtx = copy_rtx (to_rtx);
--- gcc/testsuite/gcc.dg/20031202-1.c.jj	2003-12-02 18:35:45.000000000 +0100
+++ gcc/testsuite/gcc.dg/20031202-1.c	2003-12-02 18:32:08.000000000 +0100
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-options "-O2 -mcpu=i686" { target i?86-*-* } } */
+
+extern void abort (void);
+extern void exit (int);
+
+struct A { char p[6]; } __attribute__((packed));
+struct B {
+    struct A a;
+    void * const b;
+    struct A const * const c;
+    struct A const *d;
+};
+
+char v;
+
+int __attribute__((noinline))
+foo (struct B *b)
+{
+  int i;
+  for (i = 0; i < 6; ++i)
+    if (b->a.p[i])
+      abort ();
+  if (b->b != &v || b->c || b->d)
+    abort ();
+  return 12;
+}
+
+int __attribute__((noinline))
+bar (void *x)
+{
+  __asm __volatile ("" : "=r" (x) : "0" (x));
+  struct B y = { .b = x, .c = (void *) 0 };
+  return foo (&y) + 1;
+}
+
+int
+main (void)
+{
+  if (bar (&v) != 13)
+    abort ();
+  exit (0);
+}

	Jakub


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