NetBSD Problem Report #46388

From sjamaan@frohike.homeunix.org  Sun Apr 29 14:53:05 2012
Return-Path: <sjamaan@frohike.homeunix.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
	by www.NetBSD.org (Postfix) with ESMTP id 5C36563B86B
	for <gnats-bugs@gnats.NetBSD.org>; Sun, 29 Apr 2012 14:53:05 +0000 (UTC)
Message-Id: <20120429145147.342ECF7E02D@frohike.homeunix.org>
Date: Sun, 29 Apr 2012 16:51:47 +0200 (CEST)
From: Peter.Bex@xs4all.nl
Reply-To: Peter.Bex@xs4all.nl
To: gnats-bugs@gnats.NetBSD.org
Subject: pow() behaves inconsistently and not POSIXly correct
X-Send-Pr-Version: 3.95

>Number:         46388
>Category:       standards
>Synopsis:       pow(1, inf) results in NaN or 1.0 in different situations
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    standards-manager
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Apr 29 14:55:00 +0000 2012
>Closed-Date:    Tue May 01 06:08:11 +0000 2012
>Last-Modified:  Tue May 01 06:08:11 +0000 2012
>Originator:     Peter Bex
>Release:        NetBSD 5.0.1_PATCH
>Organization:
N/A
>Environment:


System: NetBSD frohike.homeunix.org 5.0.1_PATCH NetBSD 5.0.1_PATCH (FROHIKE) #0: Tue Aug 11 22:31:56 CEST 2009 sjamaan@frohike.homeunix.org:/usr/obj/sys/arch/amd64/compile/FROHIKE amd64
Architecture: x86_64
Machine: amd64
>Description:
	The pow() function does not behave like the specification at
	http://pubs.opengroup.org/onlinepubs/9699919799/functions/pow.html
	says it should for infinity (and NaN?) values.

	Worse, gcc seems to optimize calls to pow with constant values away
	and replace it with POSIXly correct values, which means the result
	may differ depending on how the code is structured and possibly also
	on which optimization level is chosen.

	See below for the offending code.

>How-To-Repeat:
	$ cat test.c
	#include <stdio.h>
	#include <math.h>
	int main(void) {

	        double m1 = 1.0, m2 = -1.0/0.0;

       		printf("directly: pow(%f, %f) = %lf\n", (double)1.0, (double)-1.0/0.0, pow(1.0, -1.0/0.0));
        	printf("indirectly: pow(%f, %f) = %lf\n", m1, m2, pow(m1, m2));

	        return 0;
	}

	$ gcc -lm test.c
	$ ./a.out
	directly: pow(1.000000, -inf) = 1.000000
	indirectly: pow(1.000000, -inf) = nan

	This is obviously inconsistent, and SuS says the second line is
	wrong:

	"For any value of y (including NaN), if x is +1, 1.0 shall be returned."

	Looking at the generated assembly, there's only one call to
	the pow function (and when commenting out the "indirect" line and
	compiling/linking without libm I get no error), so it looks like
	GCC decides to optimize away this call, even though I specified
	no optimization level.

	By the way, the spec also says:
	"If x is -1, and y is ±Inf, 1.0 shall be returned."
	This goes wrong as well:

	directly: pow(-1.000000, -inf) = nan
	indirectly: pow(-1.000000, -inf) = nan


	Looking at the generated assembly, this contains two calls
	to pow().  I don't know why GCC decides not to optimize away
	pow(-1.0, -1.0/0.0) but it does for pow(1.0, -1.0/0.0)....

>Fix:
	No patch since this code is a little above my head, but
	it looks like the problem occurs in src/lib/libm/src/e_pow.c:145

	That line reads
		 return  y - y;	/* inf**+-1 is NaN */
	but just above, it says
		if (iy==0x7ff00000) {	/* y is +-inf */
	this means that the comment on line 145 is wrong, and I think the
	returned value is wrong as well because this seems to be the
	branch that's taken for pow(1, -inf).

>Release-Note:

>Audit-Trail:

State-Changed-From-To: open->closed
State-Changed-By: jruoho@NetBSD.org
State-Changed-When: Tue, 01 May 2012 06:08:11 +0000
State-Changed-Why:

I will close this as duplicate of PR lib/45372 (but see also port-amd64/45391).
There is also a test case (with expected failure) for this particular bug
(tests/lib/libm/t_pow, 'pow_one_neg_x').

But feel free to append any notes  to the above PRs. As you noted, NetBSD's
libm implementation and modern gcc do not play well together.




>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-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.