Subject: lib/8315: ARM32 bad floating point comparisons with NaNs
To: None <gnats-bugs@gnats.netbsd.org>
From: Richard Earnshaw <rearnsha@cambridge.arm.com>
List: netbsd-bugs
Date: 09/03/1999 04:35:52
>Number: 8315
>Category: lib
>Synopsis: ARM32 bad floating point comparisons with NaNs
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: lib-bug-people (Library Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Sep 3 04:35:01 1999
>Last-Modified:
>Originator: Richard Earnshaw
>Organization:
ARM
--
>Release: -current <NetBSD-current source date>
>Environment:
System: NetBSD shark1 1.4K NetBSD 1.4K (SHARK) #44: Mon Aug 30 17:37:22 BST 1999 rearnsha@shark1:/usr/src/sys/arch/arm32/compile/SHARK arm32
>Description:
The soft-float library for the arm32 port gets comparisons with NaNs
wrong. This is because it assumes that "<" can be implemented as
"Not (>=)". This is invalid if either operand is a NaN, since
such comparisons are unordered should always be false.
An additional enhancement could also be made to the soft-float code,
in that the implementation has hooks to raise an exception, but
currently doesn't do anything. It would be reasonable for this hook
to "raise(SIGFPE)".
>How-To-Repeat:
The following test case demonstrates the problem, note it also
applies if double is replaced with float.
#include <signal.h>
double nan = 1.0/0.0 - 1.0/0.0;
double x = 1.0;
void leave ()
{
exit (0);
}
main ()
{
signal (SIGFPE, leave);
/* NaN is an IEEE unordered operand. All these test should be false. */
if (nan == nan)
abort ();
if (nan != x) x = 1.0;
else abort ();
if (nan < x) abort ();
if (nan > x) abort ();
if (nan <= x) abort ();
if (nan >= x) abort ();
if (nan == x) abort ();
exit (0);
}
>Fix:
The __gtsf __gesf __gtdf & __gedf functions all need to take NaNs
into correctly account. It isn't correct to use the corresponding
less-than function and reverse the result.
>Audit-Trail:
>Unformatted: