From 393f9fedf35f006eb9c8c5ca185ae99aa2a0cce6 Mon Sep 17 00:00:00 2001 From: Joern Rennecke Date: Sun, 16 Jun 2013 14:59:41 +0000 Subject: [PATCH] re PR rtl-optimization/57425 (RTL alias analysis unprepared to handle stack slot sharing) gcc: PR rtl-optimization/57425 PR rtl-optimization/57569 * alias.c (write_dependence_p): Add new parameters mem_size, 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: 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. Index: alias.c =================================================================== --- alias.c (revision 200126) From-SVN: r200133 --- gcc/ChangeLog | 12 +++++++ gcc/alias.c | 42 ++++++++++++++++++++---- gcc/cse.c | 4 +-- gcc/cselib.c | 4 +-- gcc/rtl.h | 2 ++ gcc/testsuite/ChangeLog | 7 ++++ gcc/testsuite/gcc.dg/torture/pr57425-1.c | 37 +++++++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr57425-2.c | 31 +++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr57425-3.c | 31 +++++++++++++++++ gcc/testsuite/gcc.dg/torture/pr57569.c | 37 +++++++++++++++++++++ 10 files changed, 196 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr57425-1.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr57425-2.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr57425-3.c create mode 100644 gcc/testsuite/gcc.dg/torture/pr57569.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3b3044f21893..f6eee2328557 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2013-06-16 Joern Rennecke + + PR rtl-optimization/57425 + PR rtl-optimization/57569 + * alias.c (write_dependence_p): Add new parameters mem_size, + 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. + 2013-06-16 Jürgen Urban * config/mips/mips.h (ISA_HAS_LL_SC): Exclude TARGET_MIPS5900. diff --git a/gcc/alias.c b/gcc/alias.c index ef11c6a2b9ce..902ed334769b 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -156,7 +156,8 @@ 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, enum machine_mode, rtx, const_rtx, + bool, bool); static void memory_modified_1 (rtx, const_rtx, void *); @@ -2553,15 +2554,22 @@ 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 MEM_CANONCALIZED is nonzero, CANON_MEM_ADDR is the canonicalized + address of MEM, and MEM_MODE the mode for that access. */ static int -write_dependence_p (const_rtx mem, const_rtx x, int writep) +write_dependence_p (const_rtx mem, enum machine_mode mem_mode, + rtx canon_mem_addr, const_rtx x, + bool mem_canonicalized, bool writep) { rtx x_addr, mem_addr; rtx base; int ret; + gcc_checking_assert (mem_canonicalized ? (canon_mem_addr != NULL_RTX) + : (canon_mem_addr == NULL_RTX && mem_mode == VOIDmode)); + if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) return 1; @@ -2612,9 +2620,15 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep) return 0; x_addr = canon_rtx (x_addr); - mem_addr = canon_rtx (mem_addr); + if (mem_canonicalized) + mem_addr = canon_mem_addr; + else + { + mem_addr = canon_rtx (mem_addr); + mem_mode = GET_MODE (mem); + } - if ((ret = memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr, + if ((ret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr, SIZE_FOR_MODE (x), x_addr, 0)) != -1) return ret; @@ -2629,7 +2643,20 @@ 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, VOIDmode, NULL_RTX, x, + /*mem_canonicalized=*/false, /*writep=*/false); +} + +/* Likewise, but we already have a canonicalized MEM_ADDR for MEM. + Also, consider MEM in MEM_MODE (which might be from an enclosing + STRICT_LOW_PART / ZERO_EXTRACT). */ + +int +canon_anti_dependence (const_rtx mem, enum machine_mode mem_mode, + rtx mem_addr, const_rtx x) +{ + return write_dependence_p (mem, mem_mode, mem_addr, x, + /*mem_canonicalized=*/true, /*writep=*/false); } /* Output dependence: X is written after store in MEM takes place. */ @@ -2637,7 +2664,8 @@ 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, VOIDmode, NULL_RTX, x, + /*mem_canonicalized=*/false, /*writep=*/true); } diff --git a/gcc/cse.c b/gcc/cse.c index f2c8f635d39d..7e6c5184a85b 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -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 (d->exp, d->mode, d->addr, *x); else return 0; } diff --git a/gcc/cselib.c b/gcc/cselib.c index 589e41ed3dfb..2c73535c12b4 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -2263,8 +2263,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 (mem_rtx, GET_MODE (mem_rtx), + mem_addr, x)) { has_mem = true; num_mems++; diff --git a/gcc/rtl.h b/gcc/rtl.h index 554da54fc6ea..a489aaca7542 100644 --- 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, enum machine_mode, rtx, + const_rtx); extern int output_dependence (const_rtx, const_rtx); extern int may_alias_p (const_rtx, const_rtx); extern void init_alias_target (void); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 39381e277deb..da5bb5b16c2a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2013-06-16 Joern Rennecke + + 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. + 2013-06-15 Mikael Morin PR fortran/49074 diff --git a/gcc/testsuite/gcc.dg/torture/pr57425-1.c b/gcc/testsuite/gcc.dg/torture/pr57425-1.c new file mode 100644 index 000000000000..8ca85cafe6de --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr57425-1.c @@ -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 index 000000000000..ccb546e0ee78 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr57425-2.c @@ -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 index 000000000000..8e0c7fe2dec0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr57425-3.c @@ -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 index 000000000000..f036d559d6c7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr57569.c @@ -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; +} -- 2.43.5