summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-16 14:59:41 +0000
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-16 14:59:41 +0000
commitddba76b84c757d93b4247713d558724776149b62 (patch)
tree287eb151099ae1ad14535d80694e42ba6df3f9d0
parent5e524dea5f455c74f08c3e91f14f60e2f2f81369 (diff)
downloadgcc-ddba76b84c757d93b4247713d558724776149b62.tar.gz
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) git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@200133 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/alias.c42
-rw-r--r--gcc/cse.c4
-rw-r--r--gcc/cselib.c4
-rw-r--r--gcc/rtl.h2
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57425-1.c37
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57425-2.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57425-3.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57569.c37
10 files changed, 196 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3b3044f2189..f6eee232855 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+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_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 <JuergenUrban@gmx.de>
* config/mips/mips.h (ISA_HAS_LL_SC): Exclude TARGET_MIPS5900.
diff --git a/gcc/alias.c b/gcc/alias.c
index ef11c6a2b9c..902ed334769 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 f2c8f635d39..7e6c5184a85 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 589e41ed3df..2c73535c12b 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 554da54fc6e..a489aaca754 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 39381e277de..da5bb5b16c2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+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.
+
2013-06-15 Mikael Morin <mikael@gcc.gnu.org>
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 00000000000..8ca85cafe6d
--- /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 00000000000..ccb546e0ee7
--- /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 00000000000..8e0c7fe2dec
--- /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 00000000000..f036d559d6c
--- /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;
+}