This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/27390] [4.2 Regression] gcc.target/x86_64/abi/test_complex_returning.c execution fails at -O0
- From: "bonzini at gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 26 May 2006 07:46:53 -0000
- Subject: [Bug target/27390] [4.2 Regression] gcc.target/x86_64/abi/test_complex_returning.c execution fails at -O0
- References: <bug-27390-10053@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- 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