===================================================================
@@ -156,7 +156,7 @@ 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, unsigned, rtx, const_rtx, int);
static void memory_modified_1 (rtx, const_rtx, void *);
@@ -2553,10 +2553,12 @@ 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 nonzero, a write to) MEM.
+ If CANON_MEM_ADDR is nonzero, it is the canonicalized address of MEM. */
static int
-write_dependence_p (const_rtx mem, const_rtx x, int writep)
+write_dependence_p (const_rtx mem, unsigned mem_size, rtx canon_mem_addr,
+ const_rtx x, int writep)
{
rtx x_addr, mem_addr;
rtx base;
@@ -2612,9 +2614,14 @@ write_dependence_p (const_rtx mem, const
return 0;
x_addr = canon_rtx (x_addr);
- mem_addr = canon_rtx (mem_addr);
+ if (canon_mem_addr)
+ mem_addr = canon_mem_addr;
+ else
+ mem_addr = canon_rtx (mem_addr);
+ if (!mem_size)
+ mem_size = SIZE_FOR_MODE (mem);
- if ((ret = memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
+ if ((ret = memrefs_conflict_p (mem_size, mem_addr,
SIZE_FOR_MODE (x), x_addr, 0)) != -1)
return ret;
@@ -2629,7 +2636,19 @@ 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, 0, NULL_RTX, x, /*writep=*/0);
+}
+
+/* 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, GET_MODE_SIZE (mem_mode), mem_addr,
+ x, /*writep=*/0);
}
/* Output dependence: X is written after store in MEM takes place. */
@@ -2637,7 +2656,7 @@ 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, 0, NULL_RTX, x, /*writep=*/1);
}
===================================================================
@@ -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;
}
===================================================================
@@ -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++;
===================================================================
@@ -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, 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);
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}