This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Possible optimization bug on i386
- From: Will Newton <wnewton at cmedltd dot com>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 8 May 2003 18:04:05 +0100
- Subject: Possible optimization bug on i386
- Organization: Cmed
(Please CC any replies, as I am not subscribed)
I have some code (the CLISP LISP interpreter) that exhibits a segfault at
runtime when compiled with gcc 3.x and -O1 or above. Compiling with -O0 and
all flags I know of in -O1[1] is unaffected. gcc 2.9x used to compile this
code OK with -O2. From debugging and looking at the assembler generated, I
believe there is a instruction that is failing to be generated.
In this code %ebx is used as an internal stack register for the interpreter.
The code is compiled -fomit-frame-pointer.
The line in question looks like this when not optimized or with[1]:
movl %ebx, -36(%ebp) # save old stack
movl object_tab+1104, %eax # copy symbol to eax
movl %eax, (%ebx) # push symbol on stack
addl $4, %ebx # inc stack
movl $lisp_completion_ignore, (%ebx) # push func
addl $4, %ebx # inc stack
movl $0, (%ebx) # push zero
addl $4, %ebx # inc stack
movl %ebx, %eax
subl -36(%ebp), %eax
subl $1946157052, %eax
movl %eax, (%ebx) # push value
addl $4, %ebx # inc stack
When optimized with -O1 I get:
movl %ebx, %edx
movl object_tab+1104, %eax
movl %eax, (%ebx)
addl $4, %ebx
movl $lisp_completion_ignore, (%ebx)
addl $4, %ebx
movl $0, (%ebx)
addl $4, %ebx
movl %ebx, %eax
subl %edx, %eax
subl $1946157052, %eax
movl %eax, (%ebx)
Which is identical, but missing the final increment to the stack register.
The following line does not contain any operations that could be performing
this operation and %ebx is then saved:
subl $4, %esp
movl object_tab+28, %edx
movl -192(%ebp), %esi
movl -196(%ebp), %ecx
leal (%ecx,%esi,4), %eax
pushl %eax
pushl %ecx
pushl %edx
call *31(%edx)
movl %eax, -204(%ebp)
.loc 70 9179 0
movl %ebx, saved_STACK
After this I started looking at the RTL. I did a grep 'const_int 4' | wc -l in
the RTL at every stage of the compile within that line. All stages had 4
until the RTL dumped for the instruction combination phase, which had 3. It
would appear to suggest that instruction combination is doing away with this
instruction. I've been unable to distill the problem into a testcase, and the
code is quite large and involved. Should I file a bug in gnats? Can anyone
suggest where I might look to obtain more information? I know C well, but I
don't really know gcc internals.
Please CC any replies. Thanks.
[1] -falign-functions=4 -fdefer-pop -fomit-frame-pointer -fthread-jumps
-fpeephole -ffunction-cse -fkeep-static-consts -fpcc-struct-return -fgcse-lm
-fgcse-sm -fsched-interblock -fsched-spec -fbranch-count-reg
-fcprop-registers -fcommon -fverbose-asm -fgnu-linker -fargument-alias
-fmerge-constants -fident -fguess-branch-probability -fmath-errno
-ftrapping-math