Bug 44261 - Multiplying -1 by NaN is not valid.
Summary: Multiplying -1 by NaN is not valid.
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.4.3
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-05-24 16:22 UTC by Carlos O'Donell
Modified: 2010-05-29 14:33 UTC (History)
2 users (show)

See Also:
Host: hppa-linux-gnu
Target: hppa-linux-gnu
Build: hppa-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments
pa.md.d (926 bytes, text/plain)
2010-05-24 18:11 UTC, dave
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Carlos O'Donell 2010-05-24 16:22:40 UTC
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.
Comment 1 Richard Biener 2010-05-24 17:55:15 UTC
Well - GCC has fallback expansions for some sign-related instructions by doing
bit-fiddling instead.  I think that's whats required if the arch cannot do
a IEEE negate.
Comment 2 dave 2010-05-24 18:11:00 UTC
Subject: Re:  Multiplying -1 by NaN is not valid.

On Mon, 24 May 2010, rguenth at gcc dot gnu dot org wrote:

> Well - GCC has fallback expansions for some sign-related instructions by doing
> bit-fiddling instead.  I think that's whats required if the arch cannot do
> a IEEE negate.

I am testing the attached change to fiddle the sign bit.  It is probably
more efficient than a generic fallback.

Dave
Comment 3 dave 2010-05-24 18:11:00 UTC
Created attachment 20737 [details]
pa.md.d
Comment 4 John David Anglin 2010-05-29 14:16:34 UTC
Subject: Bug 44261

Author: danglin
Date: Sat May 29 14:16:11 2010
New Revision: 160027

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=160027
Log:
	PR target/44261
	config/pa/pa.md (negdf2_slow, negsf2_slow): New patterns.
	(negdf2): Adjust expander pattern and use negdf2_slow.
	(negsf2): Likewise.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/pa/pa.md

Comment 5 John David Anglin 2010-05-29 14:33:09 UTC
Fixed on trunk.
Comment 6 John David Anglin 2010-06-19 18:25:50 UTC
Subject: Bug 44261

Author: danglin
Date: Sat Jun 19 18:25:28 2010
New Revision: 161034

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=161034
Log:
	Backport from mainline
	2010-05-29  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	PR target/44261
	config/pa/pa.md (negdf2_slow, negsf2_slow): New patterns.
	(negdf2): Adjust expander pattern and use negdf2_slow.
	(negsf2): Likewise.


Modified:
    branches/gcc-4_5-branch/gcc/ChangeLog
    branches/gcc-4_5-branch/gcc/config/pa/pa.md

Comment 7 John David Anglin 2010-06-19 18:28:40 UTC
Subject: Bug 44261

Author: danglin
Date: Sat Jun 19 18:28:28 2010
New Revision: 161035

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=161035
Log:
	Backport from mainline
	2010-05-29  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	PR target/44261
	config/pa/pa.md (negdf2_slow, negsf2_slow): New patterns.
	(negdf2): Adjust expander pattern and use negdf2_slow.
	(negsf2): Likewise.


Modified:
    branches/gcc-4_4-branch/gcc/ChangeLog
    branches/gcc-4_4-branch/gcc/config/pa/pa.md