Subject: egcs codegen bug, more analysis
To: None <port-sparc@netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: port-sparc
Date: 08/11/1999 11:08:15
Well, a few people confirmed that my suspected codegen bug was real,
and apparently still present in -current. So I looked a bit deeper,
prompted largely by two reports that turning on the optimizer made the
crash (in the resulting compiled program) go away.
The problem is definitely a miscompilation of the nested function. As
a reminder, the code in question looks like
static int wrap(void (*fn)(unsigned char), unsigned char arg)
{
__label__ fail;
static void _fail(void)
{ goto fail;
}
[...]
}
Unoptimized, this turns into
.align 4
.type __fail.4,@function
.proc 020
__fail.4:
.stabn 68,0,12,LM1
LM1:
!#PROLOGUE# 0
save %sp,-112,%sp
!#PROLOGUE# 1
st %g2,[%fp-12]
.stabn 68,0,12,LM2
LM2:
ta 3
ld [%fp-16],%o0
add %o0,8,%o1
mov %o1,%fp
sethi %hi(L6),%o1
or %o1,%lo(L6),%o0
ld [%fp-20],%fp
ld [%fp-12],%g2
jmp %o0+0
restore
but optimized,
.align 4
.type __fail.4,@function
.proc 020
__fail.4:
.stabn 68,0,12,LM1
LM1:
!#PROLOGUE# 0
save %sp,-112,%sp
!#PROLOGUE# 1
st %g2,[%fp-12]
ta 3
add %g2,8,%fp
sethi %hi(L6),%o0
or %o0,%lo(L6),%o0
ld [%fp-16],%fp
jmp %o0+0
restore
Note that it appears that %fp should be loaded with 8 more than %g2 on
entry (since that's what the optimized - working - code does), but in
the unoptimized version, %g2 is stored to %fp-12 but the code that sets
%fp uses a value loaded from %fp-16. The difference between %fp-20 and
%fp-16 later also looks suspicious, as if the compiler had managed to
get confused by 4 bytes about stackframe offsets. (Note that when the
unoptimized code reloads %g2 before the jump, it loads it from the
correct place.)
Do we have anything NetBSD-specific in the SPARC egcs port, or is this
a real egcs bug? I can compose a bug report for the gcc people, but
don't want to report a bug to them if it's really a bug in something
we've done; that doesn't make anyone look good. :-/
I'm currently trying to find out where the bug is, but I'm having to
teach myself gcc internals first....
der Mouse
mouse@rodents.montreal.qc.ca
7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B