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
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.
Hmm, I wonder if this is related to: http://lists.apple.com/archives/Darwin-dev/2006/Mar/msg00102.html
(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?
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'
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 .
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.
Could you run the testsuite with this change and report it (to gcc-testresults and fortran mailing lists)?
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.
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
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.
4.1.x is broken for i686-darwin other ways so this is not to be fixed for there.
(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)?
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.
(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.