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
This commit is contained in:
parent
0f01f026dc
commit
d239ed56ab
5 changed files with 138 additions and 4 deletions
|
@ -1,3 +1,12 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
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
|
||||
|
|
37
gcc/testsuite/gcc.dg/torture/pr25654.c
Normal file
37
gcc/testsuite/gcc.dg/torture/pr25654.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* { 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;
|
||||
}
|
41
gcc/testsuite/gcc.target/i386/pr25654.c
Normal file
41
gcc/testsuite/gcc.target/i386/pr25654.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* { 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;
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue