This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
weird optimization in sin+cos, x86 backend
- From: Konstantin Vladimirov <konstantin dot vladimirov at gmail dot com>
- To: gcc at gcc dot gnu dot org
- Date: Fri, 3 Feb 2012 17:26:02 +0400
- Subject: weird optimization in sin+cos, x86 backend
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?
---
With best regards, Konstantin