This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/44261] New: Multiplying -1 by NaN is not valid.


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]