x86-code generation bug with gcc-3.0.2, -O2 -fomit-frame-pointer
Bernd Nottelmann
nottelm@uni-muenster.de
Fri Nov 9 08:40:00 GMT 2001
[Please cc me, I am not subscribed on this list]
Hi,
the problem occured, when I compiled joe-2.9.7 with gcc-3.0.2
(x86-linux). When I used "-O2 -fomit-frame-pointer", joe seg faulted
during reading the /etc/joerc-config file. I am not sure, if my analysis
is correct, but I think that a missing initialization of the %epb register
is the guilty.
Ok, lets have a look on a testcase (extracted from termcap.c):
================== test.c ==================
struct cap {
char *abuf; /* For terminfo compatible version */
void (*out) (); /* Character output routine */
void *outptr; /* First arg passed to output routine. Second
arg is character to write */
};
extern char *tgoto(char *, int, int);
extern char escape(char **s);
static struct cap *outcap;
void texec(struct cap *cap, char *s, int l, int a0, int a1)
{
int c, x;
int args[2];
int *a = args;
/* Do nothing if there is no string */
if (!s)
return;
if (cap->abuf) {
char *a;
a = tgoto(s, a1, a0);
return;
}
/* Copy args into array (yuk) */
args[0] = a0;
args[1] = a1;
/* Output string */
while ((c = *s++) != '\0')
if (*s)
switch (x = a[0], c = escape(&s)) {
case '.':
cap->out(cap->outptr, x);
++a;
break;
case 'r':
a[1] = x;
break;
case '>':
if (a[0] > escape(&s))
a[0] += escape(&s);
default:
cap->out(cap->outptr, c);
} else
cap->out(cap->outptr, escape(&s));
}
================== test.c ==================
(it is very difficult, to simplify the code, so it is possible, that there is
a much simpler testcase, but I did not find it!)
gcc -O2 -fomit-frame-pointer -S test.c generated the following output:
================== test.s ==================
.file "test.c"
.text
.align 16
.globl texec
.type texec,@function
texec:
pushl %ebp
pushl %edi
pushl %esi
pushl %ebx
subl $12, %esp
movl 4(%ebp), %ebp <- ebp is initialized by itself
movl %esp, %edi
movl 8(%ebp), %eax <- seg-fault occures, because the content
movl 16(%ebp), %edx of %ebp is not correctly initialized!
movl 20(%ebp), %ecx
testl %eax, %eax
je .L1
movl (%ebp), %ebx
testl %ebx, %ebx
[...]
================== test.s ==================
Especially it depends very strongly on the lines within the while-loop,
which assembler code is produced and if the registers get values from
n(%epb) or from n(%esp).
(It seems that correct code is generated, if -fomit-frame-pointer
is omitted).
Hope this bug report helps
Bernd
PS: gcc -v
Reading specs from /usr/lib/gcc-lib/i686-pc-linux-gnu/3.0.2/specs
Configured with: ../configure --prefix=/usr --enable-shared \
--enable-threads=posix
Thread model: posix
gcc version 3.0.2
More information about the Gcc-bugs
mailing list