alias.c (nonoverlapping_component_refs_p): Take two rtx arguments.
authorMichael Matz <matz@suse.de>
Tue, 12 Jun 2012 11:52:41 +0000 (11:52 +0000)
committerMichael Matz <matz@gcc.gnu.org>
Tue, 12 Jun 2012 11:52:41 +0000 (11:52 +0000)
* alias.c (nonoverlapping_component_refs_p): Take two rtx arguments.
(nonoverlapping_memrefs_p): Don't call it here ...
(true_dependence_1): ... but here.

testsuite/
* gcc.dg/torture/alias-1.c: New test.

From-SVN: r188448

gcc/ChangeLog
gcc/alias.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/alias-1.c [new file with mode: 0644]

index 152d47860f70b0f04b1469ee3c2948ef41f2d18f..213703c13dd8abd4f982e4ec68b6642aaa3d97a0 100644 (file)
@@ -1,3 +1,9 @@
+2012-06-12  Michael Matz  <matz@suse.de>
+
+       * alias.c (nonoverlapping_component_refs_p): Take two rtx arguments.
+       (nonoverlapping_memrefs_p): Don't call it here ...
+       (true_dependence_1): ... but here.
+
 2012-06-12  Richard Guenther  <rguenther@suse.de>
 
        * emit-rtl.c (set_mem_attributes_minus_bitpos): Remove dead code.
index fbc4e1031d9be907a9875325cc3df108cafc90a1..c11b13f3657eefc9c77ddcfc6e71e736e12e3c04 100644 (file)
@@ -156,7 +156,7 @@ static rtx find_base_value (rtx);
 static int mems_in_disjoint_alias_sets_p (const_rtx, const_rtx);
 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_tree, const_tree);
+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);
 
@@ -2181,11 +2181,15 @@ read_dependence (const_rtx mem, const_rtx x)
    overlap for any pair of objects.  */
 
 static bool
-nonoverlapping_component_refs_p (const_tree x, const_tree y)
+nonoverlapping_component_refs_p (const_rtx rtlx, const_rtx rtly)
 {
+  const_tree x = MEM_EXPR (rtlx), y = MEM_EXPR (rtly);
   const_tree fieldx, fieldy, typex, typey, orig_y;
 
-  if (!flag_strict_aliasing)
+  if (!flag_strict_aliasing
+      || !x || !y
+      || TREE_CODE (x) != COMPONENT_REF
+      || TREE_CODE (y) != COMPONENT_REF)
     return false;
 
   do
@@ -2304,13 +2308,6 @@ nonoverlapping_memrefs_p (const_rtx x, const_rtx y, bool loop_invariant)
          && ! MEM_OFFSET_KNOWN_P (y)))
     return 0;
 
-  /* If both are field references, we may be able to determine something.  */
-  if (TREE_CODE (exprx) == COMPONENT_REF
-      && TREE_CODE (expry) == COMPONENT_REF
-      && nonoverlapping_component_refs_p (exprx, expry))
-    return 1;
-
-
   /* If the field reference test failed, look at the DECLs involved.  */
   moffsetx_known_p = MEM_OFFSET_KNOWN_P (x);
   if (moffsetx_known_p)
@@ -2516,6 +2513,9 @@ true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
   if (nonoverlapping_memrefs_p (mem, x, false))
     return 0;
 
+  if (nonoverlapping_component_refs_p (mem, x))
+    return 0;
+
   return rtx_refs_may_alias_p (x, mem, true);
 }
 
index 2954f59f1462c01825141d7db932503e99359dd4..1cc34844c1eca6e75c9d4bb69b4b80936eb10b3f 100644 (file)
@@ -1,3 +1,7 @@
+2012-06-12  Michael Matz  <matz@suse.de>
+
+       * gcc.dg/torture/alias-1.c: New test.
+
 2012-06-12  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/53589
diff --git a/gcc/testsuite/gcc.dg/torture/alias-1.c b/gcc/testsuite/gcc.dg/torture/alias-1.c
new file mode 100644 (file)
index 0000000..1e60341
--- /dev/null
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-options "-fschedule-insns" } */
+
+extern void abort (void) __attribute__((noreturn));
+
+struct B { int a; int b;};
+struct wrapper {
+union setconflict
+{
+  struct S { char one1; struct B b1; } s;
+  struct T { struct B b2; char two2; } t;
+} a;
+};
+
+int
+main ()
+{
+  int sum = 0;
+  int i;
+  struct wrapper w;
+  struct B *p;
+
+  p = &w.a.s.b1;
+  asm ("": "=r" (p):"0" (p));
+  p->a = 0;
+  asm ("": "=r" (p):"0" (p));
+  sum += p->a;
+
+  p = &w.a.t.b2;
+  asm ("": "=r" (p):"0" (p));
+  p->b = 1;
+  asm ("": "=r" (p):"0" (p));
+  sum += p->b;
+
+  if (sum != 1)
+    abort();
+  return 0;
+}