re PR tree-optimization/91108 (Fails to pun through unions)
authorRichard Biener <rguenther@suse.de>
Mon, 8 Jul 2019 11:46:26 +0000 (11:46 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 8 Jul 2019 11:46:26 +0000 (11:46 +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/ssa-fre-61.c: Adjust back.
* gcc.dg/tree-ssa/ssa-fre-78.c: New testcase.

From-SVN: r273232

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

index 56f2f2c596463a96cc8aee0bd177994fc18f3fc7..dbe70b9a98e5a195a72e51d172bdab555ea53c94 100644 (file)
@@ -1,3 +1,9 @@
+2019-07-08  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/91108
+       * gcc.dg/tree-ssa/ssa-fre-61.c: Adjust back.
+       * gcc.dg/tree-ssa/ssa-fre-78.c: New testcase.
+
 2019-07-08  Jim Wilson  <jimw@sifive.com>
 
        * gcc.target/riscv/shift-shift-2.c: Add one more test.
index eae4b15b7f2c769a098c432348afa72dbec1ee56..a4d9a7194bf8a05b37b3612a5570b59de3b16a20 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do link } */
-/* { dg-options "-O -fstrict-aliasing -fdump-tree-fre1-details" } */
+/* { dg-options "-O -fdump-tree-fre1-details" } */
 
 void link_error (void);
 
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 3c45adcf3266a6f353f2cf42963a16f976491427..854222a0cc2327332c0fecf9bc258adbc864e916 100644 (file)
@@ -70,6 +70,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
@@ -2248,24 +2249,10 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
       /* 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).  */
-      if (data->vn_walk_kind == VN_WALKREWRITE
-         && is_gimple_reg_type (TREE_TYPE (lhs))
+        and return the found value.  */
+      if (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)
-             || (flag_strict_aliasing
-                 && get_alias_set (lhs) != 0
-                 && ao_ref_alias_set (ref) != 0)))
+         && ref->ref)
        {
          tree *saved_last_vuse_ptr = data->last_vuse_ptr;
          /* Do not update last_vuse_ptr in vn_reference_lookup_2.  */
@@ -2284,7 +2271,14 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
              if (TREE_CODE (rhs) == SSA_NAME)
                rhs = SSA_VAL (rhs);
              if (vnresult->result
-                 && operand_equal_p (vnresult->result, rhs, 0))
+                 && operand_equal_p (vnresult->result, rhs, 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;
            }
        }