diff mbox

[4.8] backport fixes for wrong-code PR57425 and PR57569

Message ID 21284.38483.460001.624700@gargle.gargle.HOWL
State New
Headers show

Commit Message

Mikael Pettersson March 15, 2014, 6:05 p.m. UTC
This backports the fixes for wrong-code bugs PR57425 and PR57569,
both marked as 4.8 regressions, from mainline to 4.8 branch.

Tested since June last year on x86_64, powerpc64, sparc64, armv5tel,
and m68k without regressions.  According to Bill Schmidt it also
fixes a wrong-code problem for powerpc64le on IBM's 4.8 branch.

Ok for 4.8 branch?

Thanks,

/Mikael

(I don't have commit rights, but Bill has agreed to do the commit if
this backport is approved.)


gcc/

2014-03-15  Mikael Pettersson  <mikpelinux@gmail.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-15  Mikael Pettersson  <mikpelinux@gmail.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.

Comments

Richard Biener March 17, 2014, 8:39 a.m. UTC | #1
On Sat, Mar 15, 2014 at 7:05 PM, Mikael Pettersson <mikpelinux@gmail.com> wrote:
> This backports the fixes for wrong-code bugs PR57425 and PR57569,
> both marked as 4.8 regressions, from mainline to 4.8 branch.
>
> Tested since June last year on x86_64, powerpc64, sparc64, armv5tel,
> and m68k without regressions.  According to Bill Schmidt it also
> fixes a wrong-code problem for powerpc64le on IBM's 4.8 branch.
>
> Ok for 4.8 branch?

Ok.

Thanks,
Richard.

> Thanks,
>
> /Mikael
>
> (I don't have commit rights, but Bill has agreed to do the commit if
> this backport is approved.)
>
>
> gcc/
>
> 2014-03-15  Mikael Pettersson  <mikpelinux@gmail.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-15  Mikael Pettersson  <mikpelinux@gmail.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.
>
> --- gcc-4.8.2/gcc/alias.c.~1~   2013-03-05 10:40:38.000000000 +0100
> +++ gcc-4.8.2/gcc/alias.c       2014-03-15 18:18:31.402652881 +0100
> @@ -156,7 +156,9 @@ static int insert_subset_children (splay
>  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, en
>  }
>
>  /* 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
>    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
>                           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
>  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_rt
>  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);
>  }
>
>
> --- gcc-4.8.2/gcc/cse.c.~1~     2013-02-07 09:07:04.000000000 +0100
> +++ gcc-4.8.2/gcc/cse.c 2014-03-15 18:18:31.402652881 +0100
> @@ -1824,7 +1824,7 @@ flush_hash_table (void)
>        }
>  }
>
> -/* 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;
>  }
> --- gcc-4.8.2/gcc/cselib.c.~1~  2013-01-10 21:38:27.000000000 +0100
> +++ gcc-4.8.2/gcc/cselib.c      2014-03-15 18:18:31.402652881 +0100
> @@ -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++;
> --- gcc-4.8.2/gcc/rtl.h.~1~     2013-01-10 21:38:27.000000000 +0100
> +++ gcc-4.8.2/gcc/rtl.h 2014-03-15 18:18:31.402652881 +0100
> @@ -2705,6 +2705,8 @@ extern int canon_true_dependence (const_
>                                   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);
> --- gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57425-1.c.~1~      1970-01-01 01:00:00.000000000 +0100
> +++ gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57425-1.c  2014-03-15 18:17:45.272766004 +0100
> @@ -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;
> +}
> --- gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57425-2.c.~1~      1970-01-01 01:00:00.000000000 +0100
> +++ gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57425-2.c  2014-03-15 18:17:45.272766004 +0100
> @@ -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;
> +}
> --- gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57425-3.c.~1~      1970-01-01 01:00:00.000000000 +0100
> +++ gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57425-3.c  2014-03-15 18:17:45.272766004 +0100
> @@ -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;
> +}
> --- gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57569.c.~1~        1970-01-01 01:00:00.000000000 +0100
> +++ gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57569.c    2014-03-15 18:17:45.272766004 +0100
> @@ -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;
> +}
diff mbox

Patch

--- gcc-4.8.2/gcc/alias.c.~1~	2013-03-05 10:40:38.000000000 +0100
+++ gcc-4.8.2/gcc/alias.c	2014-03-15 18:18:31.402652881 +0100
@@ -156,7 +156,9 @@  static int insert_subset_children (splay
 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, en
 }
 
 /* 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
   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
 			  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
 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_rt
 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);
 }
 
 
--- gcc-4.8.2/gcc/cse.c.~1~	2013-02-07 09:07:04.000000000 +0100
+++ gcc-4.8.2/gcc/cse.c	2014-03-15 18:18:31.402652881 +0100
@@ -1824,7 +1824,7 @@  flush_hash_table (void)
       }
 }
 
-/* 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;
 }
--- gcc-4.8.2/gcc/cselib.c.~1~	2013-01-10 21:38:27.000000000 +0100
+++ gcc-4.8.2/gcc/cselib.c	2014-03-15 18:18:31.402652881 +0100
@@ -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++;
--- gcc-4.8.2/gcc/rtl.h.~1~	2013-01-10 21:38:27.000000000 +0100
+++ gcc-4.8.2/gcc/rtl.h	2014-03-15 18:18:31.402652881 +0100
@@ -2705,6 +2705,8 @@  extern int canon_true_dependence (const_
 				  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);
--- gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57425-1.c.~1~	1970-01-01 01:00:00.000000000 +0100
+++ gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57425-1.c	2014-03-15 18:17:45.272766004 +0100
@@ -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;
+}
--- gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57425-2.c.~1~	1970-01-01 01:00:00.000000000 +0100
+++ gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57425-2.c	2014-03-15 18:17:45.272766004 +0100
@@ -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;
+}
--- gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57425-3.c.~1~	1970-01-01 01:00:00.000000000 +0100
+++ gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57425-3.c	2014-03-15 18:17:45.272766004 +0100
@@ -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;
+}
--- gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57569.c.~1~	1970-01-01 01:00:00.000000000 +0100
+++ gcc-4.8.2/gcc/testsuite/gcc.dg/torture/pr57569.c	2014-03-15 18:17:45.272766004 +0100
@@ -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;
+}