This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Possible optimization bug on i386


(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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]