aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-07-08 11:46:26 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2019-07-08 11:46:26 +0000
commit08dfb1d682a707f7319aafec28edda424395dae5 (patch)
treedd659e7669e81dbe8c6fa879216ee29a505dd80a
parentb68cae81760cd158ee465466280fc0df58e6a768 (diff)
downloadgcc-08dfb1d682a707f7319aafec28edda424395dae5.zip
gcc-08dfb1d682a707f7319aafec28edda424395dae5.tar.gz
gcc-08dfb1d682a707f7319aafec28edda424395dae5.tar.bz2
re PR tree-optimization/91108 (Fails to pun through unions)
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
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-78.c27
-rw-r--r--gcc/tree-ssa-sccvn.c30
4 files changed, 46 insertions, 19 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 56f2f2c..dbe70b9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c
index eae4b15..a4d9a71 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c
@@ -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
index 0000000..4ad232e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-78.c
@@ -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. */
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 3c45adc..854222a 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -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;
}
}