On a i686 platform, the example below is miscompiled with -O1. I expect this program to print -0.96. Here's what it actually does:
$ g++ -O1 -o y y.cc $ ./y -1.288766 $ g++ -o y y.cc $ ./y -0.960000 $ The value that the optimized version prints is actually different on each run of the program. Here's the generated code for main(), .globl main .type main, @function main: pushl %ebp movl %esp, %ebp subl $24, %esp movl %ebx, -8(%ebp) movl %esi, -4(%ebp) andl $-16, %esp subl $16, %esp movl $0, 12(%esp) movl 8(%esp), %ebx ; this seems to load ebx with garbage??? movl 12(%esp), %esi fldz fstl 8(%esp) fstpl (%esp) call _Z8x_from_zdd fstpl 4(%esp) movl %ebx, 8(%esp) ; this clobbers half of the arg with ; the garbage movl %esi, 12(%esp) movl $0, (%esp) call _Z17local_to_trflocalidi movl $0, %eax movl -8(%ebp), %ebx movl -4(%ebp), %esi movl %ebp, %esp popl %ebp ret It looks to me like the error occurs during RTL generation. Here's the tree dump from the t87.final_cleanup file (slightly trimmed): void local_to_trflocal(int, double, int) (D.1741, x_loc, D.1743) { <bb 0>: printf (&"%f\n"[0], x_loc); return; } double x_from_z(double, double) (pitch, stereo) { <bb 0>: return -9.59999999999999964472863211994990706443786621094e-1 / cos (stereo); } int main() () { <bb 0>: local_to_trflocal (0, x_from_z (0.0, 0.0), 0); return 0; } But in the 00.expand file, here's the sequence leading to the local_to_trflocal() call: (insn 27 26 28 1 (set (mem/i:DF (plus:SI (reg/f:SI 56 virtual-outgoing-args) (const_int 4 [0x4])) [0 S8 A32]) (reg:DF 71)) -1 (nil) (nil)) (insn 28 27 29 1 (set (mem:DI (plus:SI (reg/f:SI 56 virtual-outgoing-args) (const_int 8 [0x8])) [0 S8 A8]) (reg:DI 68)) -1 (nil) (nil)) (insn 29 28 30 1 (set (mem:SI (reg/f:SI 56 virtual-outgoing-args) [0 S4 A32]) (const_int 0 [0x0])) -1 (nil) (nil)) (call_insn 30 29 31 1 (call (mem:QI (symbol_ref:SI ("_Z17local_to_trflocalidi") [flags 0x3] <function_decl 0xb7f0df80 local_to_trflocal>) [0 S1 A8]) (const_int 16 [0x10])) -1 (nil) (nil) (nil)) Reg 71 here is the return value from x_from_z. I don't know where the DI store to v-o-a+8 is coming from... Environment: System: Linux karma 2.6.12.1sss #2 Thu Jul 7 00:28:21 EDT 2005 i686 i686 i386 GNU/Linux Architecture: i686 <machine, os, target, libraries (multiple lines)> host: i686-pc-linux-gnu build: i686-pc-linux-gnu target: i686-pc-linux-gnu configured with: /home/sss/gcc/gcc/configure --prefix=/usr/local/gcc --enable-threads=posix --enable-long-long --enable-languages=c,c++,f95 How-To-Repeat: Compile with -O1 ----------------------------------------------------- //g++ -O1 -g -o y y.cc extern "C" double cos(double); extern "C" int printf (...); double x_from_z(double pitch=0, double stereo=0) { return -0.96/cos(stereo); } void local_to_trflocal(int, double x_loc, int=0) { printf ("%f\n", x_loc); } int main() { local_to_trflocal(0, x_from_z()); return 0; } ----------------------------------------------------- ------- Additional Comments From snyder at fnal dot gov 2005-09-08 02:31 ------- Fix: <how to correct or work around the problem, if known (multiple lines)> -- Summary: 4.1: wrong code in argument passing Product: gcc Version: 4.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: snyder at fnal dot gov CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23775