IA64 alignment problem / how to fix?
Steve Ellcey
sje@cup.hp.com
Wed Jan 19 18:48:00 GMT 2005
I am looking at the failure of gcc.c-torture/execute/20000706-2.c (with
-O0) and the gcc.dg/struct-layout-1 tests on HP-UX IA64. Attached is a
small test case built from 20000706-2.c. What I found is that the
structure being passed has an alignment requirement of 4 bytes but GCC
tries to copy the incoming argument registers that contain that
structure to memory using st8 (i.e. using DImode) and DImode on IA64
has an alignment requirement of 8 bytes.
The alignment requirement for the memory location of the argument is
being set in assign_parm_setup_block (function.c) when calling
assign_stack_local based on the structure type and it doesn't seem to
know anything about DImode which is used as the register type for the
argument by ia64_function_arg.
There seem to be two ways to fix this, one is to modify
assign_parm_setup_block to align the memory location at the max of the
BLKmode argument and DImode but I am not sure if that would be
considered acceptable or how to specify it in a machine independent
manner.
The other way I think I can fix it is to have ia64_function_arg return a
PARALLEL instead of a regular REG for it's argument. However when I
tried this (removed the size check in ia64_function_arg and always
returned a PARALLEL for structures on big-endian machines) my bootstrap
broke. This also generates less efficient code because assumes the
memory location is not aligned and does more stores and has other code
to compensate for that fact.
Part of my problem may be that I am slightly confused as to what
ia64_function_arg should do for a structure that is larger then one
register. Currently it seems to just return the first register and it
is not clear to me who figures out that more registers are also needed.
Anyway, I'd like to force the memory allocated for the structure
argument to have the more strict alignment, is there a way I could do
this that would be considered acceptable?
Steve Ellcey
sje@cup.hp.com
-------------
Test case that aborts on ia64 HP-UX with -O0:
extern void abort(void);
extern void exit(int);
struct baz {
int a, b, c, d, e;
};
void foo(int z, struct baz x)
{
if (x.a != 1)
abort();
}
int main()
{
struct baz x;
x.a = 1;
x.b = 2;
x.c = 3;
x.d = 4;
x.e = 5;
foo(0, x);
exit(0);
}
More information about the Gcc
mailing list