The following testcase is an example of code used in a glibc testcase. I'm trying hard to shake out the bugs in the glibc testsuite for debian, and one testsuite failure looks like a compiler issue.
The expected behaviour is for the testcase to print the raw IEEE754 value of -NAN. The observed behaviour, when -DALT is on the command line, is that the testcase prints the incorrect raw value e.g. NAN. GCC 4.4.3 in debian doesn't compile this code correctly. cat >> tst-mul-nan.c <<EOF #include <stdio.h> #include <math.h> #ifdef ALT volatile double nanval; #else #define nanval NAN #endif int main () { #ifdef ALT nanval = NAN; #endif printf ("0x%llx\n", -nanval); return 0; } EOF gcc -g3 -O0 -save-temps -o test-mul-nan-OK test-mul-nan.c; ./test-mul-nan-OK 0xfff7ffffffffffff This is the correct result e.g. -NAN. In the correct case the compiler has already computer -NAN and it's loaded directly from the local symbol e.g. .LC1: .word -524289 .word -1 This is the case that is not working correctly: gcc -g3 -O0 -save-temps -DALT -o test-mul-nan-NG test-mul-nan.c; ./test-mul-nan-NG 0x7ff7ffffffffffff That result is not -NAN, it is NAN. This is incorrect. In the incorrect compilation the compiler loads NAN from a local constant: .LC0: .word 2146959359 .word -1 This is 0x7ff7ffffffffffff e.g. NAN. Then it loads a 64-bit double -1.0. .LC2: .word -1074790400 .word 0 In the incorrect case the compiler tries to multiply -1.0 by NAN to get a result of -NAN. addil LR'nanval-$global$,%r27 copy %r1,%r19 ldo RR'nanval-$global$(%r19),%r19 fldds 0(%r19),%fr23 ldil LR'.LC2,%r19 ldo RR'.LC2(%r19),%r19 fldds 0(%r19),%fr22 fmpy,dbl %fr23,%fr22,%fr22 This is not going to work because -1.0 times NAN is NAN, and the sign of the input will be ignored. See: PA-RISC 2.0 Architecture, Floating Coprocessor 8-23 "Operations With NaNs", and 8-24 "Sign Bit" can be referenced for information on NANs. After the multiplication fr22 still contains NAN, and that is what is printed instead of the expected result of -NAN. John David Anglin indicates: This is a bug. The code should xor the sign bit when doing negation. The existing code doesn't work for NANs. I'll try to fix negdf2 and negsf2. The problem is PA1.1 doesn't have a fneg instruction, so the above takes a bit of work to implement. You will get the correct result if you specify -march=2.0. Unfortunately I can't use -march=2.0 in this case, the C library has to work on PA1.1 class systems. -- Summary: Multiplying -1 by NaN is not valid. Product: gcc Version: 4.4.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: carlos at codesourcery dot com GCC build triplet: hppa-linux-gnu GCC host triplet: hppa-linux-gnu GCC target triplet: hppa-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44261