NetBSD Problem Report #50698

From gson@gson.org  Sat Jan 23 22:40:04 2016
Return-Path: <gson@gson.org>
Received: from mail.netbsd.org (mail.NetBSD.org [199.233.217.200])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
	by mollari.NetBSD.org (Postfix) with ESMTPS id B67C27ABF5
	for <gnats-bugs@gnats.NetBSD.org>; Sat, 23 Jan 2016 22:40:04 +0000 (UTC)
Message-Id: <20160123223955.AB49674508B@guava.gson.org>
Date: Sun, 24 Jan 2016 00:39:55 +0200 (EET)
From: gson@gson.org (Andreas Gustafsson)
Reply-To: gson@gson.org (Andreas Gustafsson)
To: gnats-bugs@gnats.NetBSD.org
Subject: hypotf() of small numbers yields infinity
X-Send-Pr-Version: 3.95

>Number:         50698
>Category:       lib
>Synopsis:       hypotf() of small numbers yields infinity
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    lib-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jan 23 22:45:00 +0000 2016
>Closed-Date:    Fri Mar 11 15:16:39 +0000 2016
>Last-Modified:  Fri Mar 11 15:16:39 +0000 2016
>Originator:     Andreas Gustafsson
>Release:        NetBSD 7.0
>Organization:

>Environment:
System: NetBSD
Architecture: x86_64
Machine: amd64
>Description:

The hypotf() function in libm incorrectly returns infinity (!) when
its arguments are small numbers such as 1e-18.

I have tested this on amd64 (7.0, real hardware), i386 (-current,
qemu), and sparc (-current, qemu), and they all behave this way.

>How-To-Repeat:

$ cat test-hypotf.c
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    float a = atof(argv[1]);
    float b = atof(argv[2]);
    float c = hypotf(a, b);
    printf("%.15g\n", c);
    return 0;
}
$ cc test-hypotf.c -lm -o test-hypotf
$ ./test-hypotf 1e-18 1e-18
inf

On a non-NetBSD-machine, the test program gives the correct result:

./a.out 1e-18 1e-18
1.41421363268178e-18

>Fix:

>Release-Note:

>Audit-Trail:
From: Rin Okuyama <okuyama@flex.phys.tohoku.ac.jp>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: lib/50698: hypotf() of small numbers yields infinity
Date: Sun, 24 Jan 2016 19:26:06 +0900

 This is because some magic numbers in e_hypotf.c are wrong. In FreeBSD,
 this bug was fixed by commit #23397:

   https://svnweb.freebsd.org/base/head/lib/msun/src/e_hypotf.c#rev23397

 I attached the minimal patch below. With this patch, I obtain (on amd64)

   % ./test-hypotf 1e-18 1e-18
   1.41421363268178e-18
   %

 Other changes have been made for libm in FreeBSD. IMO, we should merge
 reasonable ones.

 --- src/lib/libm/src/e_hypotf.c.orig	2016-01-24 18:40:38.426417738 +0900
 +++ src/lib/libm/src/e_hypotf.c	2016-01-24 19:07:19.114100741 +0900
 @@ -43,22 +43,22 @@
  	       if(hb == 0x7f800000) w = b;
  	       return w;
  	   }
 -	   /* scale a and b by 2**-60 */
 -	   ha -= 0x5d800000; hb -= 0x5d800000;	k += 60;
 +	   /* scale a and b by 2**-68 */
 +	   ha -= 0x22000000; hb -= 0x22000000;	k += 68;
  	   SET_FLOAT_WORD(a,ha);
  	   SET_FLOAT_WORD(b,hb);
  	}
  	if(hb < 0x26800000) {	/* b < 2**-50 */
  	    if(hb <= 0x007fffff) {	/* subnormal b or 0 */
  	        if(hb==0) return a;
 -		SET_FLOAT_WORD(t1,0x3f000000);	/* t1=2^126 */
 +		SET_FLOAT_WORD(t1,0x7e800000);	/* t1=2^126 */
  		b *= t1;
  		a *= t1;
  		k -= 126;
 -	    } else {		/* scale a and b by 2^60 */
 -	        ha += 0x5d800000; 	/* a *= 2^60 */
 -		hb += 0x5d800000;	/* b *= 2^60 */
 -		k -= 60;
 +	    } else {		/* scale a and b by 2^68 */
 +	        ha += 0x22000000; 	/* a *= 2^68 */
 +		hb += 0x22000000;	/* b *= 2^68 */
 +		k -= 68;
  		SET_FLOAT_WORD(a,ha);
  		SET_FLOAT_WORD(b,hb);
  	    }

From: "Andreas Gustafsson" <gson@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/50698 CVS commit: src/lib/libm/src
Date: Sun, 24 Jan 2016 20:34:31 +0000

 Module Name:	src
 Committed By:	gson
 Date:		Sun Jan 24 20:34:30 UTC 2016

 Modified Files:
 	src/lib/libm/src: e_hypotf.c

 Log Message:
 Fix incorrect magic numbers in scaling.  From FreeBSD commit 23397, by
 way of Rin Okuyama.  Fixes PR lib/50698.


 To generate a diff of this commit:
 cvs rdiff -u -r1.9 -r1.10 src/lib/libm/src/e_hypotf.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Andreas Gustafsson <gson@gson.org>
To: Rin Okuyama <okuyama@flex.phys.tohoku.ac.jp>
Cc: gnats-bugs@NetBSD.org
Subject: Re: lib/50698: hypotf() of small numbers yields infinity
Date: Mon, 25 Jan 2016 17:01:25 +0200

 Rin Okuyama wrote:
 >  This is because some magic numbers in e_hypotf.c are wrong. In FreeBSD,
 >  this bug was fixed by commit #23397:
 >  
 >    https://svnweb.freebsd.org/base/head/lib/msun/src/e_hypotf.c#rev23397
 >  
 >  I attached the minimal patch below. With this patch, I obtain (on amd64)
 >  
 >    % ./test-hypotf 1e-18 1e-18
 >    1.41421363268178e-18
 >    %

 Thank you for your analysis and patch.  The patch has now been committed.

 >  Other changes have been made for libm in FreeBSD. IMO, we should merge
 >  reasonable ones.

 Additional patches for the ones you think are reasonable are welcome.
 More test cases would be good, too.
 -- 
 Andreas Gustafsson, gson@gson.org

From: Rin Okuyama <okuyama@flex.phys.tohoku.ac.jp>
To: Andreas Gustafsson <gson@gson.org>
Cc: gnats-bugs@NetBSD.org
Subject: Re: lib/50698: hypotf() of small numbers yields infinity
Date: Mon, 1 Feb 2016 22:01:38 +0900

 On 2016/01/26 0:01, Andreas Gustafsson wrote:
 >>   Other changes have been made for libm in FreeBSD. IMO, we should merge
 >>   reasonable ones.
 >
 > Additional patches for the ones you think are reasonable are welcome.
 > More test cases would be good, too.

 Sorry for the late reply. I examined FreeBSD's libm, and found it much
 harder than I had imagined to merge their changes into ours.

 There are three kinds of differences: (1) trivial bug fixes as in this
 case, (2) long double functions missing in our libm, and (3) non-trivial
 changes to improve the accuracy or processing speed.

 We can readily merge (1) by patiently comparing the two implementations.

 For (2), we have not fully implemented long double functions. Instead,
 we have wrappers to double functions in src/lib/libm/src/ldbl_dummy.c.
 Needless to say, this is problematic for architectures with
 LDBL_MANT_DIG != DBL_MANT_DIG. They have long double functions both for
 LDBL_MANT_DIG == 64 (amd64, i386, ia64, and m68k), and 113 (aarch64,
 mips64, and sparc64). If we can merge it, we then have long double
 functions for all architectures except powerpc64 (LDBL_MANT_DIG == 106).

 However, for (2) and (3), there remains a big problem; how can we test
 them? Addition to ATF-based tests ported from us, they have their own
 test cases:

    https://svnweb.freebsd.org/base/head/lib/msun/tests/

 Function returns for some special arguments are checked in their test.
 But is it enough? Who can check hundreds of magic numbers?

State-Changed-From-To: open->pending-pullups
State-Changed-By: gson@NetBSD.org
State-Changed-When: Mon, 15 Feb 2016 16:20:46 +0000
State-Changed-Why:
pullup-7 #1120


From: "Martin Husemann" <martin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/50698 CVS commit: [netbsd-7] src/lib/libm/src
Date: Sun, 6 Mar 2016 18:00:08 +0000

 Module Name:	src
 Committed By:	martin
 Date:		Sun Mar  6 18:00:08 UTC 2016

 Modified Files:
 	src/lib/libm/src [netbsd-7]: e_hypotf.c

 Log Message:
 Pull up following revision(s) (requested by gson in ticket #1120):
 	lib/libm/src/e_hypotf.c: revision 1.10
 Fix incorrect magic numbers in scaling.  From FreeBSD commit 23397, by
 way of Rin Okuyama.  Fixes PR lib/50698.


 To generate a diff of this commit:
 cvs rdiff -u -r1.9 -r1.9.40.1 src/lib/libm/src/e_hypotf.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Andreas Gustafsson <gson@gson.org>
To: Rin Okuyama <okuyama@flex.phys.tohoku.ac.jp>
Cc: gnats-bugs@NetBSD.org
Subject: Re: lib/50698: hypotf() of small numbers yields infinity
Date: Fri, 11 Mar 2016 17:14:15 +0200

 On Feb 1, Rin Okuyama wrote:
 > On 2016/01/26 0:01, Andreas Gustafsson wrote:
 > >>   Other changes have been made for libm in FreeBSD. IMO, we should merge
 > >>   reasonable ones.
 > >
 > > Additional patches for the ones you think are reasonable are welcome.
 > > More test cases would be good, too.
 > 
 > Sorry for the late reply.

 Likewise :)

 > I examined FreeBSD's libm, and found it much
 > harder than I had imagined to merge their changes into ours.
 > 
 > There are three kinds of differences: (1) trivial bug fixes as in this
 > case, (2) long double functions missing in our libm, and (3) non-trivial
 > changes to improve the accuracy or processing speed.
 > 
 > We can readily merge (1) by patiently comparing the two implementations.
 > 
 > For (2), we have not fully implemented long double functions. Instead,
 > we have wrappers to double functions in src/lib/libm/src/ldbl_dummy.c.
 > Needless to say, this is problematic for architectures with
 > LDBL_MANT_DIG != DBL_MANT_DIG. They have long double functions both for
 > LDBL_MANT_DIG == 64 (amd64, i386, ia64, and m68k), and 113 (aarch64,
 > mips64, and sparc64). If we can merge it, we then have long double
 > functions for all architectures except powerpc64 (LDBL_MANT_DIG == 106).
 > 
 > However, for (2) and (3), there remains a big problem; how can we test
 > them? Addition to ATF-based tests ported from us, they have their own
 > test cases:
 > 
 >    https://svnweb.freebsd.org/base/head/lib/msun/tests/
 > 
 > Function returns for some special arguments are checked in their test.
 > But is it enough? Who can check hundreds of magic numbers?

 These are all good questions, but I'm afraid I don't have the answers.
 In any case, the specific bug reported in this PR has now been fixed
 and pulled up to -7, so I will close the PR.  If you have suggestions
 for additional tests or fixes, either for hypotf() or for libm in
 general, feel free to submit them as separate PRs.
 -- 
 Andreas Gustafsson, gson@gson.org

State-Changed-From-To: pending-pullups->closed
State-Changed-By: gson@NetBSD.org
State-Changed-When: Fri, 11 Mar 2016 15:16:39 +0000
State-Changed-Why:
Pullup done.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.