[4.8] backport fixes for wrong-code PR57425 and PR57569
Richard Biener
richard.guenther@gmail.com
Mon Mar 17 08:48:00 GMT 2014
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;
> +}
More information about the Gcc-patches
mailing list