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