Bug 34261

Summary: Directed rounding doesn't work on MacOS X
Product: gcc Reporter: John Pryce <j.d.pryce>
Component: targetAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: gcc-bugs
Priority: P3    
Version: 4.0.1   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:

Description John Pryce 2007-11-28 12:07:44 UTC
I research in interval arithmetic. I bought a MacBook Pro in Spring 07 ( MacBookPro2,2; Intel Core 2 Duo 2.33 GHz; Mac OS X 10.4.11 (8S2167), Darwin 8.11.1). 
Within MATLAB (Version 7.4.0.287 (R2007a) Jan 2007) I wanted to use Rump's interval library INTLAB. On startup, INTLAB detected the needed changing of rounding-mode wasn't working, and I couldn't fix it. 
So I tried a simple C program to check this with gcc as follows
/*--------roundtest.cpp--------*/
#include <iostream>
#include <fenv.h>
using namespace std;
int main(int argc, char* argv[]) {
  int flag;
  double x, y;
  double z0, z1, z2, z3;
  x = atof(argv[1]);
  y = atof(argv[2]);
  
  flag = fesetround(0); // round toward 0
  fprintf(stdout, "fesetround(0) returned %i\n", flag);
  fprintf(stdout, "Then fegetround() returned %i\n", fegetround());
  z0 = x/y;
  flag = fesetround(1); // round to nearest
  fprintf(stdout, "fesetround(1) returned %i\n", flag);
  fprintf(stdout, "Then fegetround() returned %i\n", fegetround());
  z1 = x/y;
  flag = fesetround(2); // round toward +oo
  fprintf(stdout, "fesetround(2) returned %i\n", flag);
  fprintf(stdout, "Then fegetround() returned %i\n", fegetround());
  z2 = x/y;
  flag = fesetround(3); // round toward -oo
  fprintf(stdout, "fesetround(3) returned %i\n", flag);
  fprintf(stdout, "Then fegetround() returned %i\n", fegetround());
  z3 = x/y;
  
  fesetround(1); // round to nearest
  fprintf(stdout, "z0=%20.18f, z1=%20.18f, z2-z1=%g, z1-z3=%g\n",
          z0, z1, z2-z1, z1-z3);

  return 0;
}
/*--------------*/
I compiled with this (I am a C++ beginner, for some reason "gcc" compiles but can't link):
johnpryce 49$ g++ -frounding-math -Wall roundtest.cpp -o roundtest

Then I ran with this, for instance
johnpryce 54$roundtest 1 3
fesetround(0) returned 0
Then fegetround() returned 0
fesetround(1) returned 1
Then fegetround() returned 0
fesetround(2) returned 1
Then fegetround() returned 0
fesetround(3) returned 1
Then fegetround() returned 0
z0=0.333333333333333315, z1=0.333333333333333315, z2-z1=0, z1-z3=0

With correct rounding, z2 and z3 MUST be different, and z1 equals one of them.
But the fesetround/fegetround output seems to show
(a) Rounding mode can't be changed
(b) It is always toward zero (i.e. oldfashioned IBM360 style chopping) if this output is to be believed. This violates the IEEE754 standard, which of course mandates rounding to nearest as the default.

Actually I think rounding to nearest is what DOES happen - big number-crunching calculations seem too accurate to be consistent with chopping - so the fesetround/fegetround functions must be wrong.
Comment 1 Andrew Pinski 2007-11-28 17:08:55 UTC
I doubt that this is a gcc bug.
Comment 2 John Pryce 2007-11-30 12:40:02 UTC
Subject: Re:  Directed rounding doesn't work on MacOS X

Dear Pinskia

On 28 Nov 2007, at 17:08, pinskia at gcc dot gnu dot org wrote:
> ------- Comment #1 from pinskia at gcc dot gnu dot org  2007-11-28  
> 17:08 -------
> I doubt that this is a gcc bug.

Consider this. Suppose I just downloaded the vanilla GCC system on to  
the shiny new Mac from which I am writing. And I find everything  
works fine except that whenever I use fprintf(), it crashes the  
system. I report this as a bug, and I get back the comment
                 "I doubt that this is a gcc bug."

In a strict sense maybe not. fprintf() in GCC works fine on other  
Unix-based systems. The trouble would be that GCC's communication  
with the OS kernel somehow screwed up on this particular system. So  
you can blame the kernel, not GCC. This is way beyond my capability  
as a user to fix or even understand, so I have to rely on you experts  
to fix it.

Of course as it's fprintf() that's crashing, you wouldn't say, in  
effect, "It's none of my business, guvnor". You would aim to fix it  
ASAP, because a C++ system without fprintf() is simply not credible.

Interval arithmetic IA is in a unique position. It *also* relies on a  
basic and simple communication with the OS, namely the ability to  
switch rounding mode. If you can do this, your IA software works. If  
you can't, it doesn't.

When it works, it can *provably* get correct answers to problems that  
are hard or even impractical by other means, e.g. see chapter 4 by  
Stan Wagon in the "100 dollar, 100 digit challenge" book.

The hardware hooks to switch rounding mode are there on any IEEE754- 
compliant CPU, as this one is. Languages support it: e.g. C has  
fegetround/fegetround.

The trouble seems to be that the detail of how rounding mode is  
handled at machine instruction level varies widely between machines.  
E.g. is the mode a global flag in the floating-point unit or is it  
encoded within each FP instruction? So perhaps it is tricky to make  
it work on each new architecture. While making fprintf() work is  
routine.

Tricky though it may be, the buck stops at you compiler writers.  
Interval computation is an increasingly important mainstream  
scientific computing activity. We interval folk haven't the skills to  
make it work on a new machine. If you don't help us, who will?

John Pryce
j.d.pryce@ntlworld.com



Comment 3 Andrew Pinski 2007-11-30 22:20:29 UTC
(In reply to comment #2)
> In a strict sense maybe not. fprintf() in GCC works fine on other  
> Unix-based systems. The trouble would be that GCC's communication  
> with the OS kernel somehow screwed up on this particular system. So  
> you can blame the kernel, not GCC. This is way beyond my capability  
> as a user to fix or even understand, so I have to rely on you experts  
> to fix it.

Lets put it this way.  If fprintf failed, it does not mean it is a GCC bug as GCC does not provide the fprintf library function.  Yes GCC could have an ABI bug but that would mean everything else would be broken but since just fprintf is broken, it is most likely a bug in fprintf.

> Interval arithmetic IA is in a unique position. It *also* relies on a  
> basic and simple communication with the OS, namely the ability to  
> switch rounding mode. If you can do this, your IA software works. If  
> you can't, it doesn't.

Well since fesetround is not provided by GCC, it is provided by the system.  Also are you using Apple's provided GCC, if so please file a bug with them.  We cannot support their modified version anyways.

> This violates the IEEE754 standard, which of course mandates rounding to
> nearest as the default.

Of course x87 violates it anyways.

When I ran the test on a x86 machine, I get:
apinski@debian:~$ ./a.out 1 3
fesetround(0) returned 0
Then fegetround() returned 0
fesetround(1) returned 1
Then fegetround() returned 0
fesetround(2) returned 1
Then fegetround() returned 0
fesetround(3) returned 1
Then fegetround() returned 0
z0=0.333333333333333315, z1=0.333333333333333315, z2-z1=0, z1-z3=0



But when I run it on a PowerPC machine (which does not violate the IEEE standard):
fesetround(0) returned 0
Then fegetround() returned 0
fesetround(1) returned 0
Then fegetround() returned 1
fesetround(2) returned 0
Then fegetround() returned 2
fesetround(3) returned 0
Then fegetround() returned 3
z0=0.333333333333333315, z1=0.333333333333333315, z2-z1=5.55112e-17, z1-z3=0


So I think this is just an x87 issue of execusive precission.

Please read bug 323.
Comment 4 John Pryce 2007-12-02 16:17:14 UTC
Subject: Re:  Directed rounding doesn't work on MacOS X

Dear Pinskia

-----------------
I did not realise that GCC does not provide these libraries. Thank  
you for explaining.

On 30 Nov 2007, at 22:20, pinskia at gcc dot gnu dot org wrote:
> ------- Comment #3 from pinskia at gcc dot gnu dot org  2007-11-30  
> 22:20 -------
> (In reply to comment #2)
> ...
> Lets put it this way.  If fprintf failed, it does not mean it is a  
> GCC bug as
> GCC does not provide the fprintf library function.  Yes GCC could  
> have an ABI
> bug but that would mean everything else would be broken but since  
> just fprintf
> is broken, it is most likely a bug in fprintf.

Does that mean, for instance, that every C compiler on this  
particular machine uses the same fprintf function? And it was written  
by Apple?

-----------------
> Well since fesetround is not provided by GCC, it is provided by the  
> system.
> Also are you using Apple's provided GCC, if so please file a bug  
> with them.  We
> cannot support their modified version anyways.

I got this in a Terminal window
> johnpryce 43$which g++
> /usr/bin/g++
>
> johnpryce 44$which gcc
> /usr/bin/gcc
>
> johnpryce 45$gcc --version
> i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc.  
> build 5367)
> Copyright (C) 2005 Free Software Foundation, Inc.
> This is free software; see the source for copying conditions.   
> There is NO
> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR  
> PURPOSE.


I see there is a folder /Developer/SDKs/MacOSX10.3.9.sdk/usr/lib/gcc/  
but don't know if this is used by the above gcc command, or is  
something separate.

How do I file a bug with Apple? I consulted Apple Help and found a  
page with these instructions
> To submit a bug report to Apple:
> Connect to the Internet.
> In the dialog that appeared when the application crashed, click the  
> submit button. ...
Which doesn't help, as it's not about crashes.

-----------------
>> This violates the IEEE754 standard, which of course mandates  
>> rounding to
>> nearest as the default.
>
> Of course x87 violates it anyways.
>
> When I ran the test on a x86 machine, I get:...

This stuff about x86 versus x87 was quite new to me.

> Please read bug 323.

Thanks. I have done so, and read the "floating-point-article.pdf".  
Very useful.

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34261
>
> ------- You are receiving this mail because: -------
> You reported the bug, or are watching the reporter.

John Pryce
j.d.pryce@ntlworld.com



Comment 5 Samuel Tardieu 2007-12-07 22:19:38 UTC
Subject: Bug 34261

Author: sam
Date: Fri Dec  7 22:19:22 2007
New Revision: 130695

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=130695
Log:
2007-12-07  Ludovic Brenta  <ludovic@ludovic-brenta.org>

    gcc/ada/
	PR ada/34261
	* mlib-tgt.adb, mlib-tgt.ads: Fix comments at the top to reflect
	the new implementation of target-specific calls.

Modified:
    trunk/gcc/ada/ChangeLog
    trunk/gcc/ada/mlib-tgt.adb
    trunk/gcc/ada/mlib-tgt.ads

Comment 6 Samuel Tardieu 2007-12-07 22:23:54 UTC
Subject: Bug 34261

Author: sam
Date: Fri Dec  7 22:23:39 2007
New Revision: 130696

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=130696
Log:
Fix wrong PR number in approved submitters comment (in ada/ChangeLog):
   PR ada/34261 -> PR ada/34361.

Corresponds to commit 130695.


Modified:
    trunk/gcc/ada/ChangeLog

Comment 7 Eric Gallager 2017-07-19 18:43:51 UTC
Closing as a duplicate of bug 323 per comments 3 and 4

*** This bug has been marked as a duplicate of bug 323 ***