Make aliasing_component_refs_p to work harder when same_type_for_tbaa returns -1
* tree-ssa-alias.c (aliasing_component_refs_p): Do not give up immediately after same_types_for_tbaa_p returns -1 and continue looking for possible exact match; if matching types are arrays watch for partial overlaps. (indirect_ref_may_alias_decl_p): Watch for partial array overlaps. (indirect_refs_may_alias_p): Do type based disambiguation first; update comment. * gcc.dg/lto/alias-access-path-2.0.c: New testcase. From-SVN: r272036
This commit is contained in:
parent
6c202d9dc6
commit
06dd9b3d4e
|
@ -1,3 +1,13 @@
|
|||
2019-06-07 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
* tree-ssa-alias.c (aliasing_component_refs_p): Do not give up
|
||||
immediately after same_types_for_tbaa_p returns -1 and continue
|
||||
looking for possible exact match; if matching types are arrays
|
||||
watch for partial overlaps.
|
||||
(indirect_ref_may_alias_decl_p): Watch for partial array overlaps.
|
||||
(indirect_refs_may_alias_p): Do type based disambiguation first;
|
||||
update comment.
|
||||
|
||||
2019-06-07 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* fwprop.c (propagate_rtx): Fix call to paradoxical_subreg_p.
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2019-06-07 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
* gcc.dg/lto/alias-access-path-2.0.c: New testcase.
|
||||
|
||||
2019-06-07 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR tree-optimization/78902
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/* { dg-lto-do run } */
|
||||
/* { dg-lto-options { { -O3 -flto -fno-early-inlining } } } */
|
||||
|
||||
/* In this test the access patch orracle (aliasing_component_refs_p)
|
||||
can disambiguage array[0] from array[1] by base+offset but it needs to be
|
||||
able to find the common type and not give up by not being able to compare
|
||||
types earlier. */
|
||||
|
||||
typedef int (*fnptr) ();
|
||||
|
||||
__attribute__ ((used))
|
||||
struct a
|
||||
{
|
||||
void *array[2];
|
||||
} a, *aptr = &a;
|
||||
|
||||
__attribute__ ((used))
|
||||
struct b
|
||||
{
|
||||
struct a a;
|
||||
} *bptr;
|
||||
|
||||
static void
|
||||
inline_me_late (int argc)
|
||||
{
|
||||
if (argc == -1)
|
||||
bptr->a.array[1] = bptr;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc)
|
||||
{
|
||||
aptr->array[0] = 0;
|
||||
inline_me_late (argc);
|
||||
if (!__builtin_constant_p (aptr->array[0] == 0))
|
||||
__builtin_abort ();
|
||||
return 0;
|
||||
}
|
|
@ -860,6 +860,7 @@ aliasing_component_refs_p (tree ref1,
|
|||
tree type1, type2;
|
||||
tree *refp;
|
||||
int same_p1 = 0, same_p2 = 0;
|
||||
bool maybe_match = false;
|
||||
|
||||
/* Choose bases and base types to search for. */
|
||||
base1 = ref1;
|
||||
|
@ -890,8 +891,14 @@ aliasing_component_refs_p (tree ref1,
|
|||
if (cmp == 0)
|
||||
{
|
||||
same_p2 = same_type_for_tbaa (TREE_TYPE (*refp), type1);
|
||||
if (same_p2 != 0)
|
||||
if (same_p2 == 1)
|
||||
break;
|
||||
/* In case we can't decide whether types are same try to
|
||||
continue looking for the exact match.
|
||||
Remember however that we possibly saw a match
|
||||
to bypass the access path continuations tests we do later. */
|
||||
if (same_p2 == -1)
|
||||
maybe_match = true;
|
||||
}
|
||||
if (!handled_component_p (*refp))
|
||||
break;
|
||||
|
@ -901,6 +908,21 @@ aliasing_component_refs_p (tree ref1,
|
|||
{
|
||||
poly_int64 offadj, sztmp, msztmp;
|
||||
bool reverse;
|
||||
|
||||
/* We assume that arrays can overlap by multiple of their elements
|
||||
size as tested in gcc.dg/torture/alias-2.c.
|
||||
This partial overlap happen only when both arrays are bases of
|
||||
the access and not contained within another component ref.
|
||||
To be safe we also assume partial overlap for VLAs. */
|
||||
if (TREE_CODE (TREE_TYPE (base1)) == ARRAY_TYPE
|
||||
&& (!TYPE_SIZE (TREE_TYPE (base1))
|
||||
|| TREE_CODE (TYPE_SIZE (TREE_TYPE (base1))) != INTEGER_CST
|
||||
|| (*refp == base2 && !ref2_is_decl)))
|
||||
{
|
||||
++alias_stats.aliasing_component_refs_p_may_alias;
|
||||
return true;
|
||||
}
|
||||
|
||||
get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp, &reverse);
|
||||
offset2 -= offadj;
|
||||
get_ref_base_and_extent (base1, &offadj, &sztmp, &msztmp, &reverse);
|
||||
|
@ -932,8 +954,10 @@ aliasing_component_refs_p (tree ref1,
|
|||
if (cmp == 0)
|
||||
{
|
||||
same_p1 = same_type_for_tbaa (TREE_TYPE (*refp), type2);
|
||||
if (same_p1 != 0)
|
||||
if (same_p1 == 1)
|
||||
break;
|
||||
if (same_p1 == -1)
|
||||
maybe_match = true;
|
||||
}
|
||||
if (!handled_component_p (*refp))
|
||||
break;
|
||||
|
@ -944,6 +968,15 @@ aliasing_component_refs_p (tree ref1,
|
|||
poly_int64 offadj, sztmp, msztmp;
|
||||
bool reverse;
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (base2)) == ARRAY_TYPE
|
||||
&& (!TYPE_SIZE (TREE_TYPE (base2))
|
||||
|| TREE_CODE (TYPE_SIZE (TREE_TYPE (base2))) != INTEGER_CST
|
||||
|| (*refp == base1 && !ref2_is_decl)))
|
||||
{
|
||||
++alias_stats.aliasing_component_refs_p_may_alias;
|
||||
return true;
|
||||
}
|
||||
|
||||
get_ref_base_and_extent (*refp, &offadj, &sztmp, &msztmp, &reverse);
|
||||
offset1 -= offadj;
|
||||
get_ref_base_and_extent (base2, &offadj, &sztmp, &msztmp, &reverse);
|
||||
|
@ -965,7 +998,7 @@ aliasing_component_refs_p (tree ref1,
|
|||
paths do not overlap and thus accesses alias only if one path can be
|
||||
continuation of another. If we was not able to decide about equivalence,
|
||||
we need to give up. */
|
||||
if (same_p1 == -1 || same_p2 == -1)
|
||||
if (maybe_match)
|
||||
return true;
|
||||
|
||||
/* If we have two type access paths B1.path1 and B2.path2 they may
|
||||
|
@ -1350,10 +1383,17 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
|
|||
For MEM_REFs we require that the component-ref offset we computed
|
||||
is relative to the start of the type which we ensure by
|
||||
comparing rvalue and access type and disregarding the constant
|
||||
pointer offset. */
|
||||
pointer offset.
|
||||
|
||||
But avoid treating variable length arrays as "objects", instead assume they
|
||||
can overlap by an exact multiple of their element size.
|
||||
See gcc.dg/torture/alias-2.c. */
|
||||
if ((TREE_CODE (base1) != TARGET_MEM_REF
|
||||
|| (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
|
||||
&& same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (dbase2)) == 1)
|
||||
&& 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);
|
||||
|
||||
if (ref1 && ref2
|
||||
|
@ -1446,22 +1486,6 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
|
|||
|| base2_alias_set == 0)
|
||||
return true;
|
||||
|
||||
/* If both references are through the same type, they do not alias
|
||||
if the accesses do not overlap. This does extra disambiguation
|
||||
for mixed/pointer accesses but requires strict aliasing. */
|
||||
if ((TREE_CODE (base1) != TARGET_MEM_REF
|
||||
|| (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
|
||||
&& (TREE_CODE (base2) != TARGET_MEM_REF
|
||||
|| (!TMR_INDEX (base2) && !TMR_INDEX2 (base2)))
|
||||
&& same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) == 1
|
||||
&& same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) == 1
|
||||
&& same_type_for_tbaa (TREE_TYPE (ptrtype1),
|
||||
TREE_TYPE (ptrtype2)) == 1
|
||||
/* But avoid treating arrays as "objects", instead assume they
|
||||
can overlap by an exact multiple of their element size. */
|
||||
&& TREE_CODE (TREE_TYPE (ptrtype1)) != ARRAY_TYPE)
|
||||
return ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2);
|
||||
|
||||
/* Do type-based disambiguation. */
|
||||
if (base1_alias_set != base2_alias_set
|
||||
&& !alias_sets_conflict_p (base1_alias_set, base2_alias_set))
|
||||
|
@ -1472,6 +1496,21 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
|
|||
|| same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) != 1)
|
||||
return true;
|
||||
|
||||
/* If both references are through the same type, they do not alias
|
||||
if the accesses do not overlap. This does extra disambiguation
|
||||
for mixed/pointer accesses but requires strict aliasing. */
|
||||
if ((TREE_CODE (base1) != TARGET_MEM_REF
|
||||
|| (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
|
||||
&& (TREE_CODE (base2) != TARGET_MEM_REF
|
||||
|| (!TMR_INDEX (base2) && !TMR_INDEX2 (base2)))
|
||||
&& same_type_for_tbaa (TREE_TYPE (ptrtype1),
|
||||
TREE_TYPE (ptrtype2)) == 1
|
||||
/* 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);
|
||||
|
||||
if (ref1 && ref2
|
||||
&& nonoverlapping_component_refs_p (ref1, ref2))
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue