alias-access-path-4.c: New testcase.

* gcc.dg/tree-ssa/alias-access-path-4.c: New testcase.
	* gcc.dg/tree-ssa/alias-access-path-5.c: New testcase.

	* tree-ssa-alias.c (aliasing_component_refs_p): Watch for arrays
	at the end of structures.

From-SVN: r272357
This commit is contained in:
Jan Hubicka 2019-06-16 19:59:02 +02:00 committed by Jan Hubicka
parent ce3a201593
commit 8e2d0529d5
5 changed files with 129 additions and 12 deletions

View File

@ -1,3 +1,8 @@
2019-06-16 Jan Hubicka <hubicka@ucw.cz>
* tree-ssa-alias.c (aliasing_component_refs_p): Watch for arrays
at the end of structures.
2019-06-16 Iain Sandoe <iain@sandoe.co.uk>
* config/darwin.c (machopic_indirect_call_target): Use renamed

View File

@ -1,3 +1,8 @@
2019-06-16 Jan Hubicka <hubicka@ucw.cz>
* gcc.dg/tree-ssa/alias-access-path-4.c: New testcase.
* gcc.dg/tree-ssa/alias-access-path-5.c: New testcase.
2019-06-15 Iain Buclaw <ibuclaw@gdcproject.org>
PR d/90650

View File

@ -0,0 +1,24 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
struct a {int v1;
int v2;};
struct b {struct a a[0];};
union c {struct b b;};
int
test (struct b *bptr1, union c *cptr, int i, int j)
{
bptr1->a[i].v1=123;
cptr->b.a[j].v2=1;
return bptr1->a[i].v1;
}
int
test2 (struct b *bptr1, union c *cptr, int i, int j)
{
bptr1->a[i].v1=124;
cptr->b.a[j].v1=1;
return bptr1->a[i].v1;
}
/* { dg-final { scan-tree-dump-times "return 123" 1 "optimized"} } */
/* { dg-final { scan-tree-dump-not "return 124" "optimized"} } */

View File

@ -0,0 +1,25 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
struct a {int v1;
int v2;};
struct b {int array[0]; struct a a[];};
union c {struct b b;};
int
test (struct b *bptr1, union c *cptr, int i, int j)
{
bptr1->a[i].v1=123;
cptr->b.a[j].v2=1;
return bptr1->a[i].v1;
}
int
test2 (struct b *bptr1, union c *cptr, int i, int j)
{
bptr1->a[i].v1=124;
cptr->b.a[j].v1=1;
return bptr1->a[i].v1;
}
/* { dg-final { scan-tree-dump-times "return 123" 1 "optimized"} } */
/* { dg-final { scan-tree-dump-not "return 124" "optimized"} } */

View File

@ -877,22 +877,62 @@ aliasing_component_refs_p (tree ref1,
tree *refp;
int same_p1 = 0, same_p2 = 0;
bool maybe_match = false;
tree end_struct_ref1 = NULL, end_struct_ref2 = NULL;
/* Choose bases and base types to search for. */
base1 = ref1;
while (handled_component_p (base1))
base1 = TREE_OPERAND (base1, 0);
{
/* Generally access paths are monotous in the size of object. The
exception are trailing arrays of structures. I.e.
struct a {int array[0];};
or
struct a {int array1[0]; int array[];};
Such struct has size 0 but accesses to a.array may have non-zero size.
In this case the size of TREE_TYPE (base1) is smaller than
size of TREE_TYPE (TREE_OPERNAD (base1, 0)).
Because we compare sizes of arrays just by sizes of their elements,
we only need to care about zero sized array fields here. */
if (TREE_CODE (base1) == COMPONENT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (base1, 1))) == ARRAY_TYPE
&& (!TYPE_SIZE (TREE_TYPE (TREE_OPERAND (base1, 1)))
|| integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_OPERAND (base1, 1)))))
&& array_at_struct_end_p (base1))
{
gcc_checking_assert (!end_struct_ref1);
end_struct_ref1 = base1;
}
base1 = TREE_OPERAND (base1, 0);
}
type1 = TREE_TYPE (base1);
base2 = ref2;
while (handled_component_p (base2))
base2 = TREE_OPERAND (base2, 0);
{
if (TREE_CODE (base2) == COMPONENT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (base2, 1))) == ARRAY_TYPE
&& (!TYPE_SIZE (TREE_TYPE (TREE_OPERAND (base2, 1)))
|| integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_OPERAND (base2, 1)))))
&& array_at_struct_end_p (base2))
{
gcc_checking_assert (!end_struct_ref2);
end_struct_ref2 = base2;
}
base2 = TREE_OPERAND (base2, 0);
}
type2 = TREE_TYPE (base2);
/* Now search for the type1 in the access path of ref2. This
would be a common base for doing offset based disambiguation on.
This however only makes sense if type2 is big enough to hold type1. */
int cmp_outer = compare_type_sizes (type2, type1);
if (cmp_outer >= 0)
/* If type2 is big enough to contain type1 walk its access path.
We also need to care of arrays at the end of structs that may extend
beyond the end of structure. */
if (cmp_outer >= 0
|| (end_struct_ref2
&& compare_type_sizes (TREE_TYPE (end_struct_ref2), type1) >= 0))
{
refp = &ref2;
while (true)
@ -900,7 +940,11 @@ aliasing_component_refs_p (tree ref1,
/* We walk from inner type to the outer types. If type we see is
already too large to be part of type1, terminate the search. */
int cmp = compare_type_sizes (type1, TREE_TYPE (*refp));
if (cmp < 0)
if (cmp < 0
&& (!end_struct_ref1
|| compare_type_sizes (TREE_TYPE (end_struct_ref1),
TREE_TYPE (*refp)) < 0))
break;
/* If types may be of same size, see if we can decide about their
equality. */
@ -957,13 +1001,18 @@ aliasing_component_refs_p (tree ref1,
}
/* If we didn't find a common base, try the other way around. */
if (cmp_outer <= 0)
if (cmp_outer <= 0
|| (end_struct_ref1
&& compare_type_sizes (TREE_TYPE (end_struct_ref1), type1) <= 0))
{
refp = &ref1;
while (true)
{
int cmp = compare_type_sizes (type2, TREE_TYPE (*refp));
if (cmp < 0)
if (cmp < 0
&& (!end_struct_ref2
|| compare_type_sizes (TREE_TYPE (end_struct_ref2),
TREE_TYPE (*refp)) < 0))
break;
/* If types may be of same size, see if we can decide about their
equality. */
@ -1024,6 +1073,9 @@ aliasing_component_refs_p (tree ref1,
if there is no B2 in the tail of path1 and no B1 on the
tail of path2. */
if (compare_type_sizes (TREE_TYPE (ref2), type1) >= 0
&& (!end_struct_ref1
|| compare_type_sizes (TREE_TYPE (ref2),
TREE_TYPE (end_struct_ref1)) >= 0)
&& type_has_components_p (TREE_TYPE (ref2))
&& (base1_alias_set == ref2_alias_set
|| alias_set_subset_of (base1_alias_set, ref2_alias_set)))
@ -1034,6 +1086,9 @@ aliasing_component_refs_p (tree ref1,
/* If this is ptr vs. decl then we know there is no ptr ... decl path. */
if (!ref2_is_decl
&& compare_type_sizes (TREE_TYPE (ref1), type2) >= 0
&& (!end_struct_ref2
|| compare_type_sizes (TREE_TYPE (ref1),
TREE_TYPE (end_struct_ref2)) >= 0)
&& type_has_components_p (TREE_TYPE (ref1))
&& (base2_alias_set == ref1_alias_set
|| alias_set_subset_of (base2_alias_set, ref1_alias_set)))
@ -1477,8 +1532,9 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
&& same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (dbase2)) == 1
&& (TREE_CODE (TREE_TYPE (base1)) != ARRAY_TYPE
|| (TYPE_SIZE (TREE_TYPE (base1))
&& TREE_CODE (TYPE_SIZE (TREE_TYPE (base1))) == INTEGER_CST)))
return ranges_maybe_overlap_p (doffset1, max_size1, doffset2, max_size2);
&& TREE_CODE (TYPE_SIZE (TREE_TYPE (base1))) == INTEGER_CST))
&& !ranges_maybe_overlap_p (doffset1, max_size1, doffset2, max_size2))
return false;
if (ref1 && ref2
&& nonoverlapping_component_refs_p (ref1, ref2))
@ -1558,8 +1614,9 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
{
poly_offset_int moff1 = mem_ref_offset (base1) << LOG2_BITS_PER_UNIT;
poly_offset_int moff2 = mem_ref_offset (base2) << LOG2_BITS_PER_UNIT;
return ranges_maybe_overlap_p (offset1 + moff1, max_size1,
offset2 + moff2, max_size2);
if (!ranges_maybe_overlap_p (offset1 + moff1, max_size1,
offset2 + moff2, max_size2))
return false;
}
if (!ptr_derefs_may_alias_p (ptr1, ptr2))
return false;
@ -1598,8 +1655,9 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
/* But avoid treating arrays as "objects", instead assume they
can overlap by an exact multiple of their element size.
See gcc.dg/torture/alias-2.c. */
&& TREE_CODE (TREE_TYPE (ptrtype1)) != ARRAY_TYPE)
return ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2);
&& TREE_CODE (TREE_TYPE (ptrtype1)) != ARRAY_TYPE
&& !ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))
return false;
if (ref1 && ref2
&& nonoverlapping_component_refs_p (ref1, ref2))