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/pr91091-1.c: New testcase.
	* gcc.dg/tree-ssa/ssa-fre-78.c: Likewise.

From-SVN: r273233
This commit is contained in:
Richard Biener 2019-07-08 11:48:48 +00:00 committed by Richard Biener
parent d542f941ca
commit 21c034217c
5 changed files with 74 additions and 15 deletions

View 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

View 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

View File

@ -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;
}

View File

@ -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. */

View 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;
}
}