Bug 26712 - gfortran on mac intel runtime floating point exception when printing
Summary: gfortran on mac intel runtime floating point exception when printing
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libfortran (show other bugs)
Version: 4.2.0
: P3 normal
Target Milestone: 4.2.0
Assignee: Francois-Xavier Coudert
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-03-16 12:29 UTC by Charles Ballard
Modified: 2006-04-01 21:26 UTC (History)
4 users (show)

See Also:
Host: i386-apple-darwin8.5.1
Target: i386-apple-darwin8.5.1
Build: i386-apple-darwin8.5.1
Known to work:
Known to fail:
Last reconfirmed: 2006-03-30 22:04:44


Attachments
fpu configuration file for mactel, uses apple supplied fenv.h (1.19 KB, text/plain)
2006-03-16 14:30 UTC, Charles Ballard
Details
fpu-387.h based fpe control for mactel (1.44 KB, text/plain)
2006-03-17 11:30 UTC, Charles Ballard
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Charles Ballard 2006-03-16 12:29:36 UTC
All attempts to run code compiled with gfortran fail if there is a floating point print.  This seems to be 
due to a floating point underflow exception being invoked.

cat test.f
      program test
      real a
      a = 10.0
      print *,a
      stop
      end

gdb stack trace follows:

(gdb) run
Starting program: /Users/charlesb/a.out 
Reading symbols for shared libraries .++ done

Program received signal EXC_ARITHMETIC, Arithmetic exception.
0x900e5158 in __gdtoa ()
(gdb) where
#0  0x900e5158 in __gdtoa ()
#1  0x900e47f8 in __ldtoa ()
#2  0x9000c947 in __vfprintf ()
#3  0x9000baf0 in sprintf ()
#4  0x0024d968 in output_float (dtp=0xbfffefb0, f=0x400390, value=10) at ../../../gcc-4.1.0/
libgfortran/io/write.c:472
#5  0x0024e597 in write_float (dtp=0xbfffefb0, f=0xbfffef08, source=0x3ff40000 <Address 
0x3ff40000 out of bounds>, len=4) at ../../../gcc-4.1.0/libgfortran/io/write.c:898
#6  0x0024e6a9 in write_real (dtp=0xbfffefb0, source=0xbfffe368 "", length=1072955392) at ../../../
gcc-4.1.0/libgfortran/io/write.c:1390
#7  0x0024f06d in *__gfortrani_list_formatted_write (dtp=0xbfffefb0, type=BT_REAL, p=0xbffff0c0, 
kind=4, size=4, nelems=1) at ../../../gcc-4.1.0/libgfortran/io/write.c:1460
#8  0x002486f0 in *__gfortran_transfer_real (dtp=0xbfffefb0, p=0xbffff0c0, kind=4) at ../../../
gcc-4.1.0/libgfortran/io/transfer.c:1079
#9  0x00001ebb in MAIN__ () at test.f:4
#10 0x00001efc in main (argc=-1073745608, argv=0x1de6) at ../../../gcc-4.1.0/libgfortran/fmain.c:
18

Specs of compiler version:
Using built-in specs.
Target: i386-apple-darwin8.5.1
Configured with: ../gcc-4.1.0/configure --enable-languages=c,c++,fortran,java
Thread model: posix
gcc version 4.1.0
Comment 1 Charles Ballard 2006-03-16 12:35:06 UTC
I have played with this some more, and it seems to be an floating point underflow.  Default configure results in FPU_HOST_HEADER=config/fpu-387.h, however, Darwin on i386 uses a fenv.h that is similar to that in config/fpu-glibc.h. 

By editing fpu-glibc.h I can run test.f successfully.
Comment 2 Andrew Pinski 2006-03-16 13:17:22 UTC
Hmm, I wonder if this is related to:
http://lists.apple.com/archives/Darwin-dev/2006/Mar/msg00102.html
Comment 3 Andrew Pinski 2006-03-16 13:32:06 UTC
(In reply to comment #1)
> I have played with this some more, and it seems to be an floating point
> underflow.  Default configure results in FPU_HOST_HEADER=config/fpu-387.h,
> however, Darwin on i386 uses a fenv.h that is similar to that in
> config/fpu-glibc.h. 

Are you saying that fpu-387.h is not working correctly so you used fpu-glibc.h but modified it for darwin's fenv.h?
Comment 4 Charles Ballard 2006-03-16 14:30:29 UTC
Created attachment 11058 [details]
fpu configuration file for mactel, uses apple supplied fenv.h

For clearing this uses feclearexcept (FE_ALL_EXCEPT)
For getting a pointer to the exception control fegetexceptflag(&mode, FE_ALL_EXCEPT) is used.
For setting individual flags fesetexceptflag (&mode, FE_DENORMAL) is used.

To use this file, some changes are required to configure.host, inparticular,
host_cpu='i386'
host_os='darwin8.5.1'
Comment 5 Charles Ballard 2006-03-17 10:13:46 UTC
How do I put this.  The apple fenv.h supplied functions "work" by only setting bits in mxcsr (not cw), and then only setting bits 1-6.  Problem is that the actual working bits are in 7-12 (as in fpu-387.h).  So my little test.f runs with the default mask (all bits on).  I get the failure when using gfortran as the mxcsr bits
are all set off (same test.f as above, default compilation)

0x37f is cw
0 is cw_sse
Floating point exception

defalt cw_sse is 0x1f80 .
Comment 6 Charles Ballard 2006-03-17 11:30:20 UTC
Created attachment 11062 [details]
fpu-387.h based fpe control for mactel

The changes are to the SSE elements.  It sets a mask as for the local floating point registers.  This seems to work for the fortran code I deal with.
Comment 7 Francois-Xavier Coudert 2006-03-25 09:27:44 UTC
Could you run the testsuite with this change and report it (to gcc-testresults and fortran mailing lists)?
Comment 8 Erik Schnetter 2006-03-30 16:18:38 UTC
I had the same problem.  I replaced this file, ran the test cases, and sent the results.  The summary is

                === gfortran Summary ===

# of expected passes            12636
# of unexpected failures        1
# of expected failures          7
# of unsupported tests          46
/Users/eschnett/src/gcc-build/gcc/testsuite/gfortran/../../gfortran  version 4.2
.0 20060329 (experimental)

with the unexpected failure

FAIL: gfortran.dg/assign_2.f90  -O0  (test for excess errors)
WARNING: gfortran.dg/assign_2.f90  -O0  compilation failed to produce executable

which seems unrelated to me after looking at the source code and error message of that file.
Comment 9 Francois-Xavier Coudert 2006-03-30 22:00:26 UTC
Subject: Bug 26712

Author: fxcoudert
Date: Thu Mar 30 22:00:21 2006
New Revision: 112546

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=112546
Log:
	PR libfortran/26712
	* config/fpu-387.h: Add special case for handling of SSE
	control bit on i386-darwin.

Modified:
    trunk/libgfortran/ChangeLog
    trunk/libgfortran/config/fpu-387.h

Comment 10 Francois-Xavier Coudert 2006-03-30 22:04:44 UTC
Can someone confirm this issue is now fixed on trunk? I'd then apply the patch to 4.1 as well.

And Erik, btw, the assign_2.f90 failure is PR25765.
Comment 11 Andrew Pinski 2006-03-30 22:08:48 UTC
4.1.x is broken for i686-darwin other ways so this is not to be fixed for there.
Comment 12 Francois-Xavier Coudert 2006-04-01 10:07:37 UTC
(In reply to comment #11)
> 4.1.x is broken for i686-darwin other ways so this is not to be fixed for
> there.

If 4.1.x is broken, how do you explain that g95 (based on 4.0.3 or 4.1.0) is working on i686-darwin?

Anyway, reopening this PR for a nicer solution, maybe one that involves a generic darwin way to do this (generic for both ppc and i686)?
Comment 13 Erik Schnetter 2006-04-01 17:21:25 UTC
Regarding a generic mechanism for both ppc and i386 on Darwin:

I looked at the header files in /usr/include on my Darwin 8.5.2 system, which contain the architecture specific files for both ppc and i386.  While the ppc headers have a file fp_regs.h, there is no such file for i386.  I don't think that Darwin supports a generic architecture-independent mechanism for FPU control.

The gfortran library contains explicit machine instructions in its file fpu-387.h, which seem to be used on all i386 architectures that don't have a glibc.  How many architectures are that?  It seems to me as if this file is broken for SSE (after this patch, it remains broken on non-Darwin architectures):

The variable cw_sse has first its low 16 bits set to zero.  Then some bits are set to one.  Then the same bits are set to one depending on front-end flags.  This is pointless.  The code also uses explicit numbers to indicate the bits although perfectly nice named constants exist.

It seems to me that the whole #else branch of the #if __APPLE__ statement should be removed, together with the #if statement itself.
Comment 14 Francois-Xavier Coudert 2006-04-01 21:26:38 UTC
(In reply to comment #13)
> It seems to me that the whole #else branch of the #if __APPLE__ statement
> should be removed, together with the #if statement itself.

Right. I tested a bit with sqrt() SSE2 instructions, and it seems that the code enclosed in the __APPLE__ case does what is needed. I just commited this. Closing.