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
This commit is contained in:
Richard Biener 2019-07-08 11:46:26 +00:00 committed by Richard Biener
parent b68cae8176
commit 08dfb1d682
4 changed files with 46 additions and 19 deletions

View 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.

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

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

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