On Fri, Feb 3, 2012 at 2:26 PM, Konstantin Vladimirov <konstantin.vladimi...@gmail.com> wrote: > Hi, > > Consider minimal reproduction code: > > #include "math.h" > #include "stdio.h" > > double __attribute__ ((noinline)) > slip(double a) > { > return (cos(a) + sin(a)); > } > > int main(void) > { > double a = 4.47460300787e+182; > double slipped = slip(a); > printf("slipped = %lf\n", slipped); > return 0; > } > > Compiling on > gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3 > > First on O0: > > gcc -o sincos.64 sincos.c -O0 -lm > ./sincos.64 > slipped = -1.141385 > > That is correct. > > Next on O1: > > gcc -o sincos.64 sincos.c -O1 -lm > ./sincos.64 > slipped = -0.432436 > > That is obviously incorrect. > > Lets dive inside: on O0: > > slip: > .LFB0: > .cfi_startproc > pushq %rbp > .cfi_def_cfa_offset 16 > movq %rsp, %rbp > .cfi_offset 6, -16 > .cfi_def_cfa_register 6 > subq $16, %rsp > movsd %xmm0, -8(%rbp) > movsd -8(%rbp), %xmm0 > call cos > movsd %xmm0, -16(%rbp) > movsd -8(%rbp), %xmm0 > call sin > addsd -16(%rbp), %xmm0 > leave > ret > > we have separate sin and cos calls, and everything works fine. > > On O1: > > slip: > .LFB25: > .cfi_startproc > subq $24, %rsp > .cfi_def_cfa_offset 32 > leaq 8(%rsp), %rdi > movq %rsp, %rsi > call sincos > movsd 8(%rsp), %xmm0 > addsd (%rsp), %xmm0 > addq $24, %rsp > ret > > Here we have one sincos call, and it works wrong. > > Why gcc performs such buggy optimization, and may I switch it off > somehow? Or may be I don't understand something and problem is in my > code?
Your math library is broken then (you can verify this yourself by using sincos). You can use -fno-builtin-sincos to disable this optimization. Richard. > --- > With best regards, Konstantin