amd64/115581: [fix] -mfancy-math-387 has no effect

Bruce Evans brde at optusnet.com.au
Thu Aug 16 23:50:08 PDT 2007


The following reply was made to PR amd64/115581; it has been noted by GNATS.

From: Bruce Evans <brde at optusnet.com.au>
To: Simun Mikecin <numisemis at yahoo.com>
Cc: freebsd-gnats-submit at freebsd.org, freebsd-amd64 at freebsd.org
Subject: Re: amd64/115581: [fix] -mfancy-math-387 has no effect
Date: Fri, 17 Aug 2007 16:49:04 +1000 (EST)

 On Thu, 16 Aug 2007, Simun Mikecin wrote:
 
 >> Description:
 > 32-bit compatibility libraries on FreeBSD/amd64 are compiled using -mfancy-math-387 gcc option. As stated in gcc(1):
 >
 >       -mno-fancy-math-387
 >           Some 387 emulators do not support the "sin", "cos" and "sqrt"
 >           instructions for the 387.  Specify this option to avoid generating
 >           those instructions.  This option is the default on FreeBSD, OpenBSD
 >           and NetBSD.  This option is overridden when -march indicates that
 >           the target cpu will always have an FPU and so the instruction will
 >           not need emulation.  As of revision 2.6.1, these instructions are
 >           not generated unless you also use the -funsafe-math-optimizations
 >           switch.
 >
 > So, using just -mfancy-math-387 has no effect. It should be used in combination with -funsafe-math-optimizations or it should not be used.
 
 It should not be used, especially on amd64 systems since basic FP
 instructions are relatively fast compared with the fancy instructions
 (except for sqrt).  The 64-bit amd64 libm intentionally never uses the
 fancy instructions (except for sqrt), partly because they are not much
 faster and partly because they are much less accurate.  The fancy
 instructions are not used for float precision (unless you pessimize
 things using -mfancy-math-387) since they are about 3 times slower
 than the library versions on small args.
 
 Is -mno-fancy-math-387 still actually the default on FreeBSD (with FreeBSD's
 config/i386/freebsd.h which is quite different (mostly gratuitously different)
 from the distribution one)?  FreeBSD hasn't supported the math emulator for
 about 10 years.
 
 > --- Makefile.inc1.orig	Tue Jul 10 18:39:36 2007
 > +++ Makefile.inc1	Thu Aug 16 18:30:44 2007
 > @@ -238,7 +238,7 @@
 > .else
 > LIB32CPUTYPE=	${TARGET_CPUTYPE}
 > .endif
 > -LIB32FLAGS=	-m32 -march=${LIB32CPUTYPE} -mfancy-math-387 -DCOMPAT_32BIT \
 > +LIB32FLAGS=	-m32 -march=${LIB32CPUTYPE} -mfancy-math-387 -funsafe-math-optimizations -DCOMPAT_32BIT \
 > 		-iprefix ${LIB32TMP}/usr/ \
 > 		-L${LIB32TMP}/usr/lib32 \
 > 		-B${LIB32TMP}/usr/lib32
 
 -unsafe-math-optimizations should be named
 -broken-floating-point-optimizations and should almost never be used.  It
 should never be used for compiling FreeBSD's math library, since the library
 depends on floating point not being very broken.
 
 gcc-4.2 still says the above, but doesn't actually do the above for
 sqrt.  It inlines sqrt (but not cos or sin) without
 -funsafe-math-optimizations.  I think the difference is just due to
 inlining sqrt not actually being unsafe and the documentation of
 -ffancy-math-387 being many years out of date (this difference is not
 new).  Inlining cos and sin would be safe if the inline code were large
 enough to detect the unsafe cases, but the inline code only checks for
 the result being a NaN (?), which is more than enough for sqrt but not
 enough for cos or sin.
 
 gcc (at least in 4.2) has a -fno-math-errno option which defaults to the
 wrong thing for FreeBSD (-fmath-errno) but the correct think on Darwin.
 -funsafe-math-optimizations apparently has the apparently-undocumented
 effect of turning off on -fno-math-errno.  So -march=pentium4 gives the
 following inlining of the fancy functions:
 
 Default:
  	sqrt: inlined, bogus errno handing
  	cos, sin: not inlined
 with -fno-math-errno:
  	sqrt: inlined, optimal
  	cos, sin: not inlined
 with -funsafe-math-optimizations:
  	sqrt: inlined, optimal
  	cos, sin: inlined, broken (additional breakage only for large args)
  	cosf: inlined, optimal
  	cosf, sinf: inlined, broken (for large args, and small args near a
  		    multiple of pi/2), pessimized (only for small args)
 
 Bruce


More information about the freebsd-amd64 mailing list