]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/91108 (Fails to pun through unions)
authorRichard Biener <rguenther@suse.de>
Mon, 8 Jul 2019 11:48:48 +0000 (11:48 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 8 Jul 2019 11:48:48 +0000 (11:48 +0000)
2019-07-08  Richard Biener  <rguenther@suse.de>

PR tree-optimization/91108
* tree-ssa-sccvn.c: Include builtins.h.
(vn_reference_lookup_3): Use only alignment constraints to
verify same-valued store disambiguation.

* gcc.dg/tree-ssa/pr91091-1.c: New testcase.
* gcc.dg/tree-ssa/ssa-fre-78.c: Likewise.

From-SVN: r273233

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr91091-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-78.c [new file with mode: 0644]
gcc/tree-ssa-sccvn.c

index c0ec9df3db14cfbc7a93d763a96fe7fcec353af8..228223d1254f25198e70b8da14796977141523c6 100644 (file)
@@ -1,3 +1,10 @@
+2019-07-08  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/91108
+       * tree-ssa-sccvn.c: Include builtins.h.
+       (vn_reference_lookup_3): Use only alignment constraints to
+       verify same-valued store disambiguation.
+
 2019-07-05  Szabolcs Nagy  <szabolcs.nagy@arm.com>
 
        Backport from mainline
index f6c33e929e86569125c77b1066ebb12595e02bf2..b7bba461c107959bbcd560ee30ab58ec9676ff08 100644 (file)
@@ -1,3 +1,9 @@
+2019-07-08  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/91108
+       * gcc.dg/tree-ssa/pr91091-1.c: New testcase.
+       * gcc.dg/tree-ssa/ssa-fre-78.c: Likewise.
+
 2019-07-07  Paul Thomas  <pault@gcc.gnu.org>
 
        Backport from mainline
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr91091-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr91091-1.c
new file mode 100644 (file)
index 0000000..2ee75d9
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fno-strict-aliasing" } */
+
+struct s { int x; } __attribute__((packed));
+struct t { int x; };
+
+void __attribute__((noinline,noipa))
+swap(struct s* p, struct t* q)
+{
+  p->x = q->x;
+  q->x = p->x;
+}
+
+int main()
+{    
+  struct t a[2];
+  a[0].x = 0x12345678;
+  a[1].x = 0x98765432;
+  swap ((struct s *)((char *)a + 1), a);
+  if (a[0].x != 0x12345678)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-78.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-78.c
new file mode 100644 (file)
index 0000000..4ad232e
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fstrict-aliasing" } */
+
+union U {
+  struct A { int : 2; int x : 8; } a;
+  struct B { int : 6; int x : 8; } b;
+};
+
+int __attribute__((noipa))
+foo (union U *p, union U *q)
+{
+  p->a.x = 1;
+  q->b.x = 1;
+  return p->a.x;
+}
+
+int
+main()
+{
+  union U x;
+  if (foo (&x, &x) != x.a.x)
+    __builtin_abort ();
+  return 0;
+}
+
+/* We support arbitrary punning through unions when it happens through
+   the union type and thus p == q is valid here.  */
index b4f626000dd01c759c4f11180c4029cd2a6910ff..cd9448138295c5fbb26bcf7c64ee297735f26a7c 100644 (file)
@@ -69,6 +69,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-loop.h"
 #include "tree-scalar-evolution.h"
 #include "tree-ssa-loop-niter.h"
+#include "builtins.h"
 #include "tree-ssa-sccvn.h"
 
 /* This algorithm is based on the SCC algorithm presented by Keith
@@ -1993,23 +1994,11 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
       /* If we reach a clobbering statement try to skip it and see if
          we find a VN result with exactly the same value as the
         possible clobber.  In this case we can ignore the clobber
-        and return the found value.
-        Note that we don't need to worry about partial overlapping
-        accesses as we then can use TBAA to disambiguate against the
-        clobbering statement when looking up a load (thus the
-        VN_WALKREWRITE guard).  */
+        and return the found value.  */
       if (vn_walk_kind == VN_WALKREWRITE
          && is_gimple_reg_type (TREE_TYPE (lhs))
          && types_compatible_p (TREE_TYPE (lhs), vr->type)
-         /* The overlap restriction breaks down when either access
-            alias-set is zero.  Still for accesses of the size of
-            an addressable unit there can be no overlaps.  Overlaps
-            between different union members are not an issue since
-            activation of a union member via a store makes the
-            values of untouched bytes unspecified.  */
-         && (known_eq (ref->size, BITS_PER_UNIT)
-             || (get_alias_set (lhs) != 0
-                 && ao_ref_alias_set (ref) != 0)))
+         && ref->ref)
        {
          tree *saved_last_vuse_ptr = last_vuse_ptr;
          /* Do not update last_vuse_ptr in vn_reference_lookup_2.  */
@@ -2026,7 +2015,14 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
              vn_reference_t vnresult = (vn_reference_t) res;
              if (vnresult->result
                  && operand_equal_p (vnresult->result,
-                                     gimple_assign_rhs1 (def_stmt), 0))
+                                     gimple_assign_rhs1 (def_stmt), 0)
+                 /* We have to honor our promise about union type punning
+                    and also support arbitrary overlaps with
+                    -fno-strict-aliasing.  So simply resort to alignment to
+                    rule out overlaps.  Do this check last because it is
+                    quite expensive compared to the hash-lookup above.  */
+                 && multiple_p (get_object_alignment (ref->ref), ref->size)
+                 && multiple_p (get_object_alignment (lhs), ref->size))
                return res;
            }
        }