Commit d239ed56 by Steven Bosscher Committed by Richard Biener

re PR rtl-optimization/25654 (RTL alias analysis unprepared to handle stack slot sharing)

2006-01-23  Steven Bosscher  <stevenb.gcc@gmail.com>
	Jan Hubicka  <jh@suse.cz>
	Richard Guenther  <rguenther@suse.de>

	PR rtl-optimization/25654
	* cfgexpand.c (aggregate_contains_union_type): New function.
	(add_alias_set_conflicts): Call it.  Make sure to add conflicts
	for structure variables that contain a union type.

	* gcc.dg/torture/pr25654.c: New testcase.
	* gcc.target/i386/pr25654.c: Likewise.

Co-Authored-By: Jan Hubicka <jh@suse.cz>
Co-Authored-By: Richard Guenther <rguenther@suse.de>

From-SVN: r110109
parent 0f01f026
2006-01-23 Steven Bosscher <stevenb.gcc@gmail.com>
Jan Hubicka <jh@suse.cz>
Richard Guenther <rguenther@suse.de>
PR rtl-optimization/25654
* cfgexpand.c (aggregate_contains_union_type): New function.
(add_alias_set_conflicts): Call it. Make sure to add conflicts
for structure variables that contain a union type.
2006-01-23 Richard Sandiford <richard@codesourcery.com>
* gengtype.c (new_structure): Return the structure.
......
......@@ -272,11 +272,39 @@ stack_var_conflict_p (size_t x, size_t y)
gcc_assert (index < stack_vars_conflict_alloc);
return stack_vars_conflict[index];
}
/* Returns true if TYPE is or contains a union type. */
static bool
aggregate_contains_union_type (tree type)
{
tree field;
if (TREE_CODE (type) == UNION_TYPE
|| TREE_CODE (type) == QUAL_UNION_TYPE)
return true;
if (TREE_CODE (type) == ARRAY_TYPE)
return aggregate_contains_union_type (TREE_TYPE (type));
if (TREE_CODE (type) != RECORD_TYPE)
return false;
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
if (TREE_CODE (field) == FIELD_DECL)
if (aggregate_contains_union_type (TREE_TYPE (field)))
return true;
return false;
}
/* A subroutine of expand_used_vars. If two variables X and Y have alias
sets that do not conflict, then do add a conflict for these variables
in the interference graph. We also have to mind MEM_IN_STRUCT_P and
MEM_SCALAR_P. */
in the interference graph. We also need to make sure to add conflicts
for union containing structures. Else RTL alias analysis comes along
and due to type based aliasing rules decides that for two overlapping
union temporaries { short s; int i; } accesses to the same mem through
different types may not alias and happily reorders stores across
life-time boundaries of the temporaries (See PR25654).
We also have to mind MEM_IN_STRUCT_P and MEM_SCALAR_P. */
static void
add_alias_set_conflicts (void)
......@@ -287,12 +315,23 @@ add_alias_set_conflicts (void)
{
tree type_i = TREE_TYPE (stack_vars[i].decl);
bool aggr_i = AGGREGATE_TYPE_P (type_i);
bool contains_union;
contains_union = aggregate_contains_union_type (type_i);
for (j = 0; j < i; ++j)
{
tree type_j = TREE_TYPE (stack_vars[j].decl);
bool aggr_j = AGGREGATE_TYPE_P (type_j);
if (aggr_i != aggr_j || !objects_must_conflict_p (type_i, type_j))
if (aggr_i != aggr_j
/* Either the objects conflict by means of type based
aliasing rules, or we need to add a conflict. */
|| !objects_must_conflict_p (type_i, type_j)
/* In case the types do not conflict ensure that access
to elements will conflict. In case of unions we have
to be careful as type based aliasing rules may say
access to the same memory does not conflict. So play
safe and add a conflict in this case. */
|| contains_union)
add_stack_var_conflict (i, j);
}
}
......
2006-01-23 Steven Bosscher <stevenb.gcc@gmail.com>
Jan Hubicka <jh@suse.cz>
Richard Guenther <rguenther@suse.de>
PR rtl-optimization/25654
* gcc.dg/torture/pr25654.c: New testcase.
* gcc.target/i386/pr25654.c: Likewise.
2005-01-23 Paul Thomas <pault@gcc.gnu.org>
PR fortran/25901
/* { dg-do run } */
extern void abort (void) __attribute__((noreturn));
union setconflict
{
short a[20];
int b[10];
};
int
main ()
{
int sum = 0;
{
union setconflict a;
short *c;
c = a.a;
asm ("": "=r" (c):"0" (c));
*c = 0;
asm ("": "=r" (c):"0" (c));
sum += *c;
}
{
union setconflict a;
int *c;
c = a.b;
asm ("": "=r" (c):"0" (c));
*c = 1;
asm ("": "=r" (c):"0" (c));
sum += *c;
}
if (sum != 1)
abort();
return 0;
}
/* { dg-do run { target ilp32 } } */
/* { dg-options "-O2 -mpreferred-stack-boundary=2 -march=i686 -frename-registers" } */
extern void abort (void) __attribute__((noreturn));
struct wrapper {
union setconflict
{
short a[20];
int b[10];
} a;
};
int
main ()
{
int sum = 0;
{
struct wrapper a;
short *c;
c = a.a.a;
asm ("": "=r" (c):"0" (c));
*c = 0;
asm ("": "=r" (c):"0" (c));
sum += *c;
}
{
struct wrapper a;
int *c;
c = a.a.b;
asm ("": "=r" (c):"0" (c));
*c = 1;
asm ("": "=r" (c):"0" (c));
sum += *c;
}
if (sum != 1)
abort();
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