weird optimization in sin+cos, x86 backend
Richard Guenther
richard.guenther@gmail.com
Fri Feb 3 13:43:00 GMT 2012
On Fri, Feb 3, 2012 at 2:26 PM, Konstantin Vladimirov
<konstantin.vladimirov@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
More information about the Gcc
mailing list