]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR rtl-optimization/57425 (RTL alias analysis unprepared to handle stack...
authorMikael Pettersson <mikpelinux@gmail.com>
Mon, 17 Mar 2014 15:31:43 +0000 (15:31 +0000)
committerWilliam Schmidt <wschmidt@gcc.gnu.org>
Mon, 17 Mar 2014 15:31:43 +0000 (15:31 +0000)
gcc/

2014-03-17  Mikael Pettersson  <mikpelinux@gmail.com>
    Committed by Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

Backport from mainline:

2013-06-20  Joern Rennecke <joern.rennecke@embecosm.com>

PR rtl-optimization/57425
PR rtl-optimization/57569
* alias.c (write_dependence_p): Remove parameters mem_mode and
canon_mem_addr.  Add parameters x_mode, x_addr and x_canonicalized.
Changed all callers.
(canon_anti_dependence): Get comments and semantics in sync.
Add parameter mem_canonicalized.  Changed all callers.
* rtl.h (canon_anti_dependence): Update prototype.

2013-06-16  Joern Rennecke <joern.rennecke@embecosm.com>

PR rtl-optimization/57425
PR rtl-optimization/57569
* alias.c (write_dependence_p): Add new parameters mem_mode,
canon_mem_addr and mem_canonicalized.  Change type of writep to bool.
Changed all callers.
(canon_anti_dependence): New function.
* cse.c (check_dependence): Use canon_anti_dependence.
* cselib.c (cselib_invalidate_mem): Likewise.
* rtl.h (canon_anti_dependence): Declare.

gcc/testsuite/

2014-03-17  Mikael Pettersson  <mikpelinux@gmail.com>
    Committed by Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

Backport from mainline:

2013-06-16  Joern Rennecke <joern.rennecke@embecosm.com>

PR rtl-optimization/57425
PR rtl-optimization/57569
* gcc.dg/torture/pr57425-1.c, gcc.dg/torture/pr57425-2.c: New files.
* gcc.dg/torture/pr57425-3.c, gcc.dg/torture/pr57569.c: Likewise.

Co-Authored-By: Bill Schmidt <wschmidt@linux.vnet.ibm.com>
From-SVN: r208620

gcc/ChangeLog
gcc/alias.c
gcc/cse.c
gcc/cselib.c
gcc/rtl.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr57425-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr57425-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr57425-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr57569.c [new file with mode: 0644]

index cbefb2d6c1ffdfc1a747f6a14a73794a70dac77d..4602749d38165d9949e30a90f8a6d59a4dc8315a 100644 (file)
@@ -1,3 +1,31 @@
+2014-03-17  Mikael Pettersson  <mikpelinux@gmail.com>
+           Committed by Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       Backport from mainline:
+
+       2013-06-20  Joern Rennecke <joern.rennecke@embecosm.com>
+
+       PR rtl-optimization/57425
+       PR rtl-optimization/57569
+       * alias.c (write_dependence_p): Remove parameters mem_mode and
+       canon_mem_addr.  Add parameters x_mode, x_addr and x_canonicalized.
+       Changed all callers.
+       (canon_anti_dependence): Get comments and semantics in sync.
+       Add parameter mem_canonicalized.  Changed all callers.
+       * rtl.h (canon_anti_dependence): Update prototype.
+
+       2013-06-16  Joern Rennecke <joern.rennecke@embecosm.com>
+
+       PR rtl-optimization/57425
+       PR rtl-optimization/57569
+       * alias.c (write_dependence_p): Add new parameters mem_mode,
+       canon_mem_addr and mem_canonicalized.  Change type of writep to bool.
+       Changed all callers.
+       (canon_anti_dependence): New function.
+       * cse.c (check_dependence): Use canon_anti_dependence.
+       * cselib.c (cselib_invalidate_mem): Likewise.
+       * rtl.h (canon_anti_dependence): Declare.
+
 2014-03-17  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
index aa404a7ab499c8d4273ca6b88356a9371b2af044..381222c34872d3d2e4daa7e6015e6d07aa9d5a4e 100644 (file)
@@ -156,7 +156,9 @@ static int insert_subset_children (splay_tree_node, void*);
 static alias_set_entry get_alias_set_entry (alias_set_type);
 static bool nonoverlapping_component_refs_p (const_rtx, const_rtx);
 static tree decl_for_component_ref (tree);
-static int write_dependence_p (const_rtx, const_rtx, int);
+static int write_dependence_p (const_rtx,
+                                     const_rtx, enum machine_mode, rtx,
+                                                            bool, bool, bool);
 
 static void memory_modified_1 (rtx, const_rtx, void *);
 
@@ -2558,15 +2560,24 @@ canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
 }
 
 /* Returns nonzero if a write to X might alias a previous read from
-   (or, if WRITEP is nonzero, a write to) MEM.  */
+   (or, if WRITEP is true, a write to) MEM.
+   If X_CANONCALIZED is true, then X_ADDR is the canonicalized address of X,
+   and X_MODE the mode for that access.
+   If MEM_CANONICALIZED is true, MEM is canonicalized.  */
 
 static int
-write_dependence_p (const_rtx mem, const_rtx x, int writep)
+write_dependence_p (const_rtx mem,
+                                  const_rtx x, enum machine_mode x_mode, rtx x_addr,
+                                                bool mem_canonicalized, bool x_canonicalized, bool writep)
 {
-  rtx x_addr, mem_addr;
+  rtx mem_addr;
   rtx base;
   int ret;
 
+  gcc_checking_assert (x_canonicalized
+                             ? (x_addr != NULL_RTX && x_mode != VOIDmode)
+                                      : (x_addr == NULL_RTX && x_mode == VOIDmode));
+
   if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem))
     return 1;
 
@@ -2590,17 +2601,21 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep)
   if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
     return 1;
 
-  x_addr = XEXP (x, 0);
   mem_addr = XEXP (mem, 0);
-  if (!((GET_CODE (x_addr) == VALUE
-        && GET_CODE (mem_addr) != VALUE
-        && reg_mentioned_p (x_addr, mem_addr))
-       || (GET_CODE (x_addr) != VALUE
-           && GET_CODE (mem_addr) == VALUE
-           && reg_mentioned_p (mem_addr, x_addr))))
+  if (!x_addr)
     {
-      x_addr = get_addr (x_addr);
-      mem_addr = get_addr (mem_addr);
+      x_addr = XEXP (x, 0);
+      if (!((GET_CODE (x_addr) == VALUE
+            && GET_CODE (mem_addr) != VALUE
+            && reg_mentioned_p (x_addr, mem_addr))
+           || (GET_CODE (x_addr) != VALUE
+               && GET_CODE (mem_addr) == VALUE
+               && reg_mentioned_p (mem_addr, x_addr))))
+       {
+         x_addr = get_addr (x_addr);
+         if (!mem_canonicalized)
+           mem_addr = get_addr (mem_addr);
+       }
     }
 
   if (! writep)
@@ -2616,11 +2631,16 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep)
                          GET_MODE (mem)))
     return 0;
 
-  x_addr = canon_rtx (x_addr);
-  mem_addr = canon_rtx (mem_addr);
+  if (!x_canonicalized)
+    {
+      x_addr = canon_rtx (x_addr);
+      x_mode = GET_MODE (x);
+    }
+  if (!mem_canonicalized)
+    mem_addr = canon_rtx (mem_addr);
 
   if ((ret = memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
-                                SIZE_FOR_MODE (x), x_addr, 0)) != -1)
+                                GET_MODE_SIZE (x_mode), x_addr, 0)) != -1)
     return ret;
 
   if (nonoverlapping_memrefs_p (x, mem, false))
@@ -2634,7 +2654,23 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep)
 int
 anti_dependence (const_rtx mem, const_rtx x)
 {
-  return write_dependence_p (mem, x, /*writep=*/0);
+  return write_dependence_p (mem, x, VOIDmode, NULL_RTX,
+                                 /*mem_canonicalized=*/false,
+                                                    /*x_canonicalized*/false, /*writep=*/false);
+}
+
+/* Likewise, but we already have a canonicalized MEM, and X_ADDR for X.
+   Also, consider X in X_MODE (which might be from an enclosing
+   STRICT_LOW_PART / ZERO_EXTRACT).
+   If MEM_CANONICALIZED is true, MEM is canonicalized.  */
+
+int
+canon_anti_dependence (const_rtx mem, bool mem_canonicalized,
+                                        const_rtx x, enum machine_mode x_mode, rtx x_addr)
+{
+  return write_dependence_p (mem, x, x_mode, x_addr,
+                                 mem_canonicalized, /*x_canonicalized=*/true,
+                                                            /*writep=*/false);
 }
 
 /* Output dependence: X is written after store in MEM takes place.  */
@@ -2642,7 +2678,9 @@ anti_dependence (const_rtx mem, const_rtx x)
 int
 output_dependence (const_rtx mem, const_rtx x)
 {
-  return write_dependence_p (mem, x, /*writep=*/1);
+  return write_dependence_p (mem, x, VOIDmode, NULL_RTX,
+                                 /*mem_canonicalized=*/false,
+                                                    /*x_canonicalized*/false, /*writep=*/true);
 }
 \f
 
index 1d4507497694c1ec3c5b5d370a42505ebca5dfec..40105a9b199994221555b81d75e023447114c1a2 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -1824,7 +1824,7 @@ flush_hash_table (void)
       }
 }
 \f
-/* Function called for each rtx to check whether true dependence exist.  */
+/* Function called for each rtx to check whether an anti dependence exist.  */
 struct check_dependence_data
 {
   enum machine_mode mode;
@@ -1837,7 +1837,7 @@ check_dependence (rtx *x, void *data)
 {
   struct check_dependence_data *d = (struct check_dependence_data *) data;
   if (*x && MEM_P (*x))
-    return canon_true_dependence (d->exp, d->mode, d->addr, *x, NULL_RTX);
+    return canon_anti_dependence (*x, true, d->exp, d->mode, d->addr);
   else
     return 0;
 }
index f2021b985b05b6adfa1ad173c9a187a7b86abf5f..334d9552abf752eb8f301ab94a74fa0aeab38e0a 100644 (file)
@@ -2260,8 +2260,8 @@ cselib_invalidate_mem (rtx mem_rtx)
              continue;
            }
          if (num_mems < PARAM_VALUE (PARAM_MAX_CSELIB_MEMORY_LOCATIONS)
-             && ! canon_true_dependence (mem_rtx, GET_MODE (mem_rtx),
-                                         mem_addr, x, NULL_RTX))
+             && ! canon_anti_dependence (x, false, mem_rtx,
+                                         GET_MODE (mem_rtx), mem_addr))
            {
              has_mem = true;
              num_mems++;
index a86034eada64276177d60108b2bc23a0ff572592..91f3387c701fc8ec34cc2707cc6d8f8896187441 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2705,6 +2705,8 @@ extern int canon_true_dependence (const_rtx, enum machine_mode, rtx,
                                  const_rtx, rtx);
 extern int read_dependence (const_rtx, const_rtx);
 extern int anti_dependence (const_rtx, const_rtx);
+extern int canon_anti_dependence (const_rtx, bool,
+                                               const_rtx, enum machine_mode, rtx);
 extern int output_dependence (const_rtx, const_rtx);
 extern int may_alias_p (const_rtx, const_rtx);
 extern void init_alias_target (void);
index 09b5e1ebdc6a16ca21d5aabe9022e92ad045c3e6..c02befd7646759f197cb2da065864ad3c7056f23 100644 (file)
@@ -1,3 +1,15 @@
+2014-03-17  Mikael Pettersson  <mikpelinux@gmail.com>
+           Committed by Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       Backport from mainline:
+
+       2013-06-16  Joern Rennecke <joern.rennecke@embecosm.com>
+
+       PR rtl-optimization/57425
+       PR rtl-optimization/57569
+       * gcc.dg/torture/pr57425-1.c, gcc.dg/torture/pr57425-2.c: New files.
+       * gcc.dg/torture/pr57425-3.c, gcc.dg/torture/pr57569.c: Likewise.
+
 2014-03-17  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
@@ -13,7 +25,7 @@
        Backport from mainline
        PR libfortran/60128
        * gfortran.dg/fmt_en.f90: New test.
-       
+
 2014-03-15  Jerry DeLisle  <jvdelisle@gcc.gnu>
 
        Backport from mainline
diff --git a/gcc/testsuite/gcc.dg/torture/pr57425-1.c b/gcc/testsuite/gcc.dg/torture/pr57425-1.c
new file mode 100644 (file)
index 0000000..8ca85ca
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+
+extern void abort (void) __attribute__((noreturn));
+
+union setconflict
+{
+  int a[20];
+  long b[10];
+};
+
+int
+main ()
+{
+  int sum = 0;
+  {
+    union setconflict a;
+    int *c;
+    c = a.a;
+    asm ("": "=r" (c):"0" (c));
+    *c = 0;
+    asm ("": "=r" (c):"0" (c));
+    sum += *c;
+  }
+  {
+    union setconflict a;
+    long *c;
+    c = a.b;
+    asm ("": "=r" (c):"0" (c));
+    *c = 1;
+    asm ("": "=r" (c):"0" (c));
+    sum += *c;
+  }
+
+  if (sum != 1)
+    abort();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr57425-2.c b/gcc/testsuite/gcc.dg/torture/pr57425-2.c
new file mode 100644 (file)
index 0000000..ccb546e
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+extern void abort (void) __attribute__((noreturn));
+
+int
+main ()
+{
+  int sum = 0;
+  {
+    int a[20];
+    int *c;
+    c = a;
+    asm ("": "=r" (c):"0" (c));
+    *c = 0;
+    asm ("": "=r" (c):"0" (c));
+    sum += *c;
+  }
+  {
+    long b[10];
+    long *c;
+    c = b;
+    asm ("": "=r" (c):"0" (c));
+    *c = 1;
+    asm ("": "=r" (c):"0" (c));
+    sum += *c;
+  }
+
+  if (sum != 1)
+    abort();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr57425-3.c b/gcc/testsuite/gcc.dg/torture/pr57425-3.c
new file mode 100644 (file)
index 0000000..8e0c7fe
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+extern void abort (void) __attribute__((noreturn));
+
+int
+main ()
+{
+  int sum = 0;
+  {
+    long a[20];
+    long *c;
+    c = a;
+    asm ("": "=r" (c):"0" (c));
+    *c = 0;
+    asm ("": "=r" (c):"0" (c));
+    sum += *c;
+  }
+  {
+    long long b[10];
+    long long *c;
+    c = b;
+    asm ("": "=r" (c):"0" (c));
+    *c = 1;
+    asm ("": "=r" (c):"0" (c));
+    sum += *c;
+  }
+
+  if (sum != 1)
+    abort();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr57569.c b/gcc/testsuite/gcc.dg/torture/pr57569.c
new file mode 100644 (file)
index 0000000..f036d55
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+
+extern void abort (void) __attribute__((noreturn));
+
+struct S { int f0; } a; 
+
+int b, e, *d = &b, f;
+
+void 
+fn1 ()
+{
+  int **g[9][6];
+  int ***h = &g[6][3];
+  for (; e < 9; e++) {
+    f = 0;
+    for (; f < 6; f++)
+      g[e][f] = &d;
+  }
+  ***h = 0;
+}
+
+void
+fn2 ()
+{
+  fn1 ();
+  struct S c[4][10] = {};
+  a = c[3][9];
+}
+
+int
+main ()
+{
+  fn2 ();
+  if (a.f0 != 0)
+    abort ();
+  return 0;
+}