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