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]

[Bug target/27390] [4.2 Regression] gcc.target/x86_64/abi/test_complex_returning.c execution fails at -O0



------- Comment #6 from bonzini at gnu dot org  2006-05-26 07:46 -------
There are indeed differences in the generated code.

aj_f_times2 is equal without and with the patch.

aj_d_times2 has this (left = old, right = patched):

        movsd   %xmm0, -40(%rbp)     |         movsd   %xmm0, -32(%rbp)
        movq    -40(%rbp), %rax      |         movsd   %xmm1, -24(%rbp)
        movsd   %xmm1, -40(%rbp)     <
        movq    -40(%rbp), %rdx      <
        movq    %rax, -32(%rbp)      <
        movq    %rdx, -24(%rbp)      <

This is just better code.

The miscompiled function is aj_ld_times2, which is like this (some code moved
for clarity):

        fldt    16(%rbp)               fldt    16(%rbp)
        fadd    %st(0), %st            fadd    %st(0), %st
        fstpt   -48(%rbp)              fstpt   -48(%rbp)

So far so good.

        movq    -32(%rbp), %rax        movq    -32(%rbp), %rax
        movl    -24(%rbp), %edx        movl    -24(%rbp), %edx
        movq    %rax, -32(%rbp)        movq    %rax, -32(%rbp)
        movl    %edx, -24(%rbp)        movl    %edx, -24(%rbp)

Useless, and also accessing uninitialized memory, but this is -O0.

        fldt    32(%rbp)               fldt    32(%rbp)
        fadd    %st(0), %st            fadd    %st(0), %st
        fstpt   -32(%rbp)              fstpt   -32(%rbp)

Also good.

        movq    -48(%rbp), %rax        movq    -48(%rbp), %rax
        movl    -40(%rbp), %edx        movl    -40(%rbp), %edx
        movq    %rax, -48(%rbp)        movq    %rax, -48(%rbp)
        movl    %edx, -40(%rbp)        movl    %edx, -40(%rbp)

Useless.

        movq    -48(%rbp), %rax        movq    -48(%rbp), %rax
        movl    -40(%rbp), %edx        movl    -40(%rbp), %edx
        movq    -32(%rbp), %rcx        movq    -32(%rbp), %rcx
        movl    -24(%rbp), %ebx        movl    -24(%rbp), %ebx

These are -O0 stupidities.

        flds    .LC0(%rip)           <
        fstp    %st(0)               <
        fstp    %st(1)               <

I don't have a clue what this is for.  What is .LC0?  The only thing I'm sure
about, is that this causes a stack underflow...

        movq    %rax, -64(%rbp)        movq    %rax, -64(%rbp)
        movl    %edx, -56(%rbp)        movl    %edx, -56(%rbp)
        fldt    -64(%rbp)              fldt    -64(%rbp)
        movq    %rcx, -64(%rbp)        movq    %rcx, -64(%rbp)
        movl    %ebx, -56(%rbp)        movl    %ebx, -56(%rbp)
        fldt    -64(%rbp)              fldt    -64(%rbp)
                                     > flds    .LC0(%rip)
                                     > fstp    %st(0)
                                     > fstp    %st(1)

... the bug is that it is moved afterwards, after the result was loaded on the
stack, and the underflowing fstp clobbers the return value.

The wrong instruction is produced by a (clobber (reg/i:XC 8 st)).  The patched
GCC moves the clobber later.  The RTL produced by the patched GCC is sane until
flow2, and the messed up by the stack register conversion pass:

(insn 41 57 58 3 (set (reg:XF 10 st(2) [orig:66 <result> ] [66])
        (mem/c:XF (plus:DI (reg/f:DI 6 bp)
                (const_int -64 [0xffffffffffffffc0])) [0 S16 A8])) 99
{*movxf_integer} (nil)
    (nil))

...

(insn 43 59 25 3 (set (reg:XF 11 st(3) [orig:67 <result>+16 ] [67])
        (mem/c:XF (plus:DI (reg/f:DI 6 bp)
                (const_int -64 [0xffffffffffffffc0])) [0 S16 A8])) 99
{*movxf_integer} (nil)
    (nil))

(note 25 43 28 3 NOTE_INSN_FUNCTION_END)

(insn 28 25 29 3 (clobber (reg/i:XC 8 st)) -1 (nil)
    (nil))

(insn 29 28 30 3 (set (reg:XF 8 st [ <result> ])
        (reg:XF 10 st(2) [orig:66 <result> ] [66])) 99 {*movxf_integer} (nil)
    (nil))

(insn 30 29 35 3 (set (reg:XF 9 st(1) [+16 ])
        (reg:XF 11 st(3) [orig:67 <result>+16 ] [67])) 99 {*movxf_integer}
(nil)
    (nil))

(insn 35 30 64 3 (use (reg/i:XC 8 st)) -1 (nil)
    (nil))

Latent bug in stack, CCing sayle.


-- 

bonzini at gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |sayle at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27390


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