On Sat, Mar 15, 2014 at 7:05 PM, Mikael Pettersson <mikpeli...@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 <mikpeli...@gmail.com> > > Backport from mainline: > > 2013-06-20 Joern Rennecke <joern.renne...@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.renne...@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 <mikpeli...@gmail.com> > > Backport from mainline: > > 2013-06-16 Joern Rennecke <joern.renne...@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; > +}