Commit 17b99c98 by Jan Hubicka Committed by Jan Hubicka

alias.c (record_component_aliases): Do not simplify pointed-to types of ODR types

	* alias.c (record_component_aliases): Do not simplify pointed-to
	types of ODR types 
	* testsuite/g++.dg/lto/alias-4_0.C

From-SVN: r273552
parent a7dbb777
2019-07-17 Jan Hubicka <hubicka@ucw.cz>
* alias.c (record_component_aliases): Do not simplify pointed-to
types of ODR types
2019-07-17 Uroš Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (*andqi_2_maybe_si): Handle potential
......
......@@ -1202,47 +1202,52 @@ record_component_aliases (tree type)
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field))
if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field))
{
/* LTO type merging does not make any difference between
component pointer types. We may have
struct foo {int *a;};
as TYPE_CANONICAL of
struct bar {float *a;};
Because accesses to int * and float * do not alias, we would get
false negative when accessing the same memory location by
float ** and bar *. We thus record the canonical type as:
struct {void *a;};
void * is special cased and works as a universal pointer type.
Accesses to it conflicts with accesses to any other pointer
type. */
tree t = TREE_TYPE (field);
if (in_lto_p)
{
/* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
element type and that type has to be normalized to void *,
too, in the case it is a pointer. */
while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
{
gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
t = TREE_TYPE (t);
}
if (POINTER_TYPE_P (t))
t = ptr_type_node;
else if (flag_checking)
gcc_checking_assert (get_alias_set (t)
== get_alias_set (TREE_TYPE (field)));
}
record_alias_subset (superset, get_alias_set (t));
}
{
/* LTO non-ODR type merging does not make any difference between
component pointer types. We may have
struct foo {int *a;};
as TYPE_CANONICAL of
struct bar {float *a;};
Because accesses to int * and float * do not alias, we would get
false negative when accessing the same memory location by
float ** and bar *. We thus record the canonical type as:
struct {void *a;};
void * is special cased and works as a universal pointer type.
Accesses to it conflicts with accesses to any other pointer
type. */
bool void_pointers = in_lto_p
&& (!odr_type_p (type)
|| !odr_based_tbaa_p (type));
for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field))
if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field))
{
tree t = TREE_TYPE (field);
if (void_pointers)
{
/* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
element type and that type has to be normalized to void *,
too, in the case it is a pointer. */
while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
{
gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
t = TREE_TYPE (t);
}
if (POINTER_TYPE_P (t))
t = ptr_type_node;
else if (flag_checking)
gcc_checking_assert (get_alias_set (t)
== get_alias_set (TREE_TYPE (field)));
}
record_alias_subset (superset, get_alias_set (t));
}
}
break;
case COMPLEX_TYPE:
......
2019-07-17 Jan Hubicka <hubicka@ucw.cz>
* g++.dg/lto/alias-4_0.C
2019-07-17 Richard Biener <rguenther@suse.de>
PR tree-optimization/91178
......
/* { dg-lto-do run } */
/* { dg-lto-options { { -O3 -flto -fno-early-inlining } } } */
__attribute__ ((used))
short *ptr_init, **ptr=&ptr_init;
__attribute__ ((used))
struct a {
int *aptr;
} a, *aptr=&a;
void
write_ptr ()
{
*aptr = a;
}
__attribute__ ((used))
void
test ()
{
*ptr = (short int *)0;
write_ptr ();
if (!__builtin_constant_p (*ptr == (void *)0))
__builtin_abort ();
}
int
main()
{
test ();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment