This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Sparc bootstrap failures: alignment problem
- To: egcs-bugs at egcs dot cygnus dot com
- Subject: Sparc bootstrap failures: alignment problem
- From: Zack Weinberg <zack at rabi dot columbia dot edu>
- Date: Thu, 18 Feb 1999 13:16:12 -0500
- cc: davem at dm dot cobaltmicro dot com
For some time bootstraps on Sparc systems have been failing because
the stage1 compiled genrecog dumps core. This is due to an alignment
bug setting up the stack frame.
Test case:
static void
write_tree_1 (tree, prevpos, afterward, type)
void *tree;
const char *prevpos;
void *afterward;
char type;
{
register void *p, *p1;
register int depth;
char switch_mode = 0;
char switch_code = 0;
int uncond = 0;
char modemap[37];
char codemap[127];
int indent = 2;
int i;
memset (modemap, 0, sizeof modemap);
modemap[17] = prevpos[1];
puts(&modemap[17]);
}
int
main(void)
{
write_tree_1(0, "abcd", 0, 0);
return 0;
}
If correctly compiled, this should print "b". When compiled by stage1
gcc on Sparc with optimization, you get a bus error. memset() has
been expanded inline to a series of singleword stores, but the
modemap array isn't aligned, so we fault. Presumably gcc thinks it
can get away with not aligning modemap since it's an array of char,
but the memset expander assumes its target is aligned. (The C
standard does not allow this assumption.)
I'm using an Ultra30, `sparc-sun-solaris2.6'. It's possible that this
code works on other Sparc hardware.
As a side note, egcs-1.1 generates doubleword stores for the memset.
I don't know if the change was deliberate, if not it might be worth
investigating.
Here's the assembly output:
write_tree_1:
!#PROLOGUE# 0
save %sp, -280, %sp
!#PROLOGUE# 1
mov 0, %o0
mov 0, %o1
st %o0, [%fp-53] ; fp is suitably aligned, fp-53 isn't
st %o1, [%fp-49]
st %o0, [%fp-45]
st %o1, [%fp-41]
st %o0, [%fp-37]
st %o1, [%fp-33]
st %o0, [%fp-29]
st %o1, [%fp-25]
st %g0, [%fp-21]
stb %g0, [%fp-17]
ldub [%i1+1], %o0
stb %o0, [%fp-36]
call puts, 0
add %fp, -36, %o0
ret
restore
zw