http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51446
Bug #: 51446
Summary: -fno-trapping-math generates NaN constant with
different sign
Classification: Unclassified
Product: gcc
Version: 4.6.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
AssignedTo: [email protected]
ReportedBy: [email protected]
With this compiler:
[Bradley-Luciers-MacBook-Pro:~/Downloads] lucier% /pkgs/gcc-4.6.1/bin/gcc -v
Using built-in specs.
COLLECT_GCC=/pkgs/gcc-4.6.1/bin/gcc
COLLECT_LTO_WRAPPER=/pkgs/gcc-4.6.1/libexec/gcc/x86_64-apple-darwin10.8.0/4.6.1/lto-wrapper
Target: x86_64-apple-darwin10.8.0
Configured with: ../../gcc-4.6.1/configure --prefix=/pkgs/gcc-4.6.1
Thread model: posix
gcc version 4.6.1 (GCC)
and this code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
union double_or_long {double d; long l;}
infinity, nan1, nan2;
double temp;
infinity.d = 1.0 / 0.0;
nan1.d = infinity.d - infinity.d;
temp = 0.0 / 0.0;
nan2.d = temp;
printf("%ld %ld\n", nan1.l, nan2.l);
return 1;
}
You get
[Bradley-Luciers-MacBook-Pro:~/Downloads] lucier% /pkgs/gcc-4.6.1/bin/gcc -O1
-Wall -W nan-test-c.c
[Bradley-Luciers-MacBook-Pro:~/Downloads] lucier% ./a.out
-2251799813685248 -2251799813685248
[Bradley-Luciers-MacBook-Pro:~/Downloads] lucier% /pkgs/gcc-4.6.1/bin/gcc -O1
-Wall -W -fno-trapping-math nan-test-c.c
[Bradley-Luciers-MacBook-Pro:~/Downloads] lucier% ./a.out
9221120237041090560 9221120237041090560
If you look at the assembly, without -fno-trapping-math you get
_main:
LFB4:
subq $8, %rsp
LCFI0:
xorpd %xmm0, %xmm0
movsd LC0(%rip), %xmm1
divsd %xmm0, %xmm1
divsd %xmm0, %xmm0
movd %xmm0, %rdx
subsd %xmm1, %xmm1
movd %xmm1, %rsi
leaq LC2(%rip), %rdi
movl $0, %eax
call _printf
movl $1, %eax
addq $8, %rsp
LCFI1:
ret
i.e., the divisions and subtractions are actually executed; with
-fno-trapping-math you get
_main:
LFB4:
subq $8, %rsp
LCFI0:
movabsq $9221120237041090560, %rdx
movq %rdx, %rsi
leaq LC0(%rip), %rdi
movl $0, %eax
call _printf
movl $1, %eax
addq $8, %rsp
LCFI1:
ret
i.e., it just loads a constant for both NaNs for which the sign differs from
the value that is computed with the divsd and the subsd instructions.