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

Reply via email to