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:
parent
d542f941ca
commit
21c034217c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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. */
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue