From yabuki@fuchan.myaw.ei.meisei-u.ac.jp  Mon Apr 18 08:29:34 2011
Return-Path: <yabuki@fuchan.myaw.ei.meisei-u.ac.jp>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id DB3C4106564A
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 18 Apr 2011 08:29:34 +0000 (UTC)
	(envelope-from yabuki@fuchan.myaw.ei.meisei-u.ac.jp)
Received: from fuchan.myaw.ei.meisei-u.ac.jp (fuchan.myaw.ei.meisei-u.ac.jp [160.194.136.10])
	by mx1.freebsd.org (Postfix) with ESMTP id 875678FC13
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 18 Apr 2011 08:29:34 +0000 (UTC)
Received: from fuchan.myaw.ei.meisei-u.ac.jp (localhost [127.0.0.1])
	by fuchan.myaw.ei.meisei-u.ac.jp (8.14.3/8.14.3) with ESMTP id p3I7qUND047530
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 18 Apr 2011 16:52:30 +0900 (JST)
	(envelope-from yabuki@fuchan.myaw.ei.meisei-u.ac.jp)
Received: (from yabuki@localhost)
	by fuchan.myaw.ei.meisei-u.ac.jp (8.14.3/8.14.3/Submit) id p3I7qUrs047529;
	Mon, 18 Apr 2011 16:52:30 +0900 (JST)
	(envelope-from yabuki)
Message-Id: <201104180752.p3I7qUrs047529@fuchan.myaw.ei.meisei-u.ac.jp>
Date: Mon, 18 Apr 2011 16:52:30 +0900 (JST)
From: Michirou & <yabuki@fuchan.myaw.ei.meisei-u.ac.jp>
Reply-To: Michirou & <yabuki@fuchan.myaw.ei.meisei-u.ac.jp>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: fpsetprec does not work
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         156464
>Category:       amd64
>Synopsis:       fpsetprec does not work
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-amd64
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Apr 18 08:30:11 UTC 2011
>Closed-Date:    Thu Oct 20 02:01:21 UTC 2011
>Last-Modified:  Thu Oct 20 02:01:21 UTC 2011
>Originator:     Michirou Yabuki
>Release:        FreeBSD 8.2-RELEASE amd64
>Organization:
>Environment:
System: FreeBSD nm64 8.2-RELEASE FreeBSD GENERIC


	

amd64,  FreeBSD 8.2-RELEASE GENERIC
fpsetprec(), fpgetprec()

>Description:

	

In default, fpgetprec() returns FP_PE, but results show FP_PD.
if fpsetprec(FP_PE) is called, results are never changed.

This is not happen on FreeBSD8.2-RELEASE i386 version.


>How-To-Repeat:

#include <stdio.h>
#include <stdlib.h>
#include <machine/ieeefp.h>
int main()
{
    double a, b, c, d;

    printf("fpgetprec %d\n",   fpgetprec()); // 3 on amd64, 2 on i386

    a = 10.0;
    b = 2.718281810;
    c = a / (b * b);
    printf("%20.16e\n",   c);  // 1.3533528507465618e+00 on both

    fpsetprec(FP_PE);
    a = 10.0;
    b = 2.718281810;
    c = a / (b * b);
    printf("%20.16e\n",   c);
              // 1.3533528507465618e+00 on amd64
	      // 1.3533528507465620e+00 on i386

    exit(0);
}



>Fix:

	I don't know.

>Release-Note:
>Audit-Trail:

From: Bruce Evans <brde@optusnet.com.au>
To: Michirou & <yabuki@fuchan.myaw.ei.meisei-u.ac.jp>
Cc: FreeBSD-gnats-submit@FreeBSD.org, freebsd-amd64@FreeBSD.org
Subject: Re: amd64/156464: fpsetprec does not work
Date: Tue, 19 Apr 2011 06:02:02 +1000 (EST)

 On Mon, 18 Apr 2011, Michirou & wrote:
 
 >> Description:
 >
 > In default, fpgetprec() returns FP_PE, but results show FP_PD.
 > if fpsetprec(FP_PE) is called, results are never changed.
 
 amd64 uses SSE except for long doubles, so fpsetprec() and no effect
 on the results for long doubles.  Since the precision defaults to
 FP_PE on amd64, fpsetprec() can only be used to break long doubles
 on amd64, while on i386 the precision defaults to FP_PD and fpsetprec()
 is needed to unbreak this.  fpsetprec() on i386 can also be used to:
 - break doubles by setting the precision to FP_PS
 - reduce the precision for floats by setting the precision to FP_PS.
    This is sometimes useful for getting the same precision for floats
    as on other arches like amd64, to test that nothing depends on the
    extra precision without being ifdefed for this.
 - give increased precision for floats and doubles by setting the
    precision to FP_PE.  This may be useful, but is difficult to
    program.  It requires almost never actually using floats or
    doubles, except for converting them to and from long double on
    input and output.
 
 > This is not happen on FreeBSD8.2-RELEASE i386 version.
 
 amd64 behaviour in this area hasn't changed.
 
 >> How-To-Repeat:
 >
 > #include <stdio.h>
 > #include <stdlib.h>
 > #include <machine/ieeefp.h>
 > int main()
 > {
 >    double a, b, c, d;
 
 This only uses doubles, so fpsetprec() has no effect on it.
 
 >
 >    printf("fpgetprec %d\n",   fpgetprec()); // 3 on amd64, 2 on i386
 >
 >    a = 10.0;
 >    b = 2.718281810;
 >    c = a / (b * b);
 >    printf("%20.16e\n",   c);  // 1.3533528507465618e+00 on both
 >
 >    fpsetprec(FP_PE);
 
 It is still 3 on amd64, but is not used for doubles.  It was changed
 from 2 to 3 on i386.
 
 >    a = 10.0;
 >    b = 2.718281810;
 >    c = a / (b * b);
 >    printf("%20.16e\n",   c);
 >              // 1.3533528507465618e+00 on amd64
 > 	      // 1.3533528507465620e+00 on i386
 
 So result is more accurate on i386, but this behaviour is fragile and
 requires more care to program than the above in general.  With FP_PE
 on i386, b*b is evaluated in extra precision, but there is nothing
 to prevent it being stored to memory, which would lose its extra
 precision, especially since gcc doesn't understand precision stuff.
 In practice, gcc won't store to memory in the middle of a simple
 expression like the above, even with -O0, so the above works like
 you want.  The careful version is:
 
  	a = 10.0;
  	b = 2.718281810;
 
  	long double la, lb;
 
  	la = a;
  	lb = b;
  	c = la / (lb * lb);	/* compiler bugs -- extra precision not lost
  				 * yet unless there is an acidental or
  				 * forced store (-ffloat-store) */
  	printf("%20.16e\n",   c);  /* ABI gives a store which loses the bugs
  				    * so we see only double precision for
  				    * the result */
 
 An even more careful version to avoid the compiler bugs by forcing a store
 for this variable only is:
 
  	...
  	volatile double vc;
 
  	vc = la / (lb * lb);
  	c = vc;			/* c reduced to double prec -- now ready for
  				 * output, but probably not useful for
  				 * furthe calculations */
 
 -ffloat-store should never be used since it pessimizes speed and precision
 globally.
 
 >
 >    exit(0);
 > }
 
 fpsetprec() is very unportable due to its only affecting the i387 register
 set.  Even on i386, you can break its effect on doubles by using '-msse2
 -mfpmath=sse'.  This bug is the default for clang.
 
 Bruce
State-Changed-From-To: open->closed 
State-Changed-By: das 
State-Changed-When: Thu Oct 20 01:59:13 UTC 2011 
State-Changed-Why:  
This is an historical, deprecated interface for the x87 FPU. For an 
explanation of why it doesn't work as you expect on amd64, please see 
the manual page or Bruce's reply. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=156464 
>Unformatted:
