Hi, the attached patch updates the documentation and error messages for the -ffpe-trap= option:
- The IEEE 754 name for the "loss of precision" exception is "inexact", and not "precision" (both in 754-1985 and 754-2008). So use that instead, while still allowing precision as an alias for inexact for backwards compatibility. Also, change the name of the corresponding macro in the internal headers (ABI is not broken since the value is still the same). - The "denormal" exception is not an IEEE exception, but an additional one supported at least on x86. And the difference between underflow and denormal is, AFAICS, that underflow refers to the result of a FP operation, whereas the denormal exception means that an operand to an operation was a denormal. So try to clarify that. - In fpu-aix.h we had a bug where we enabled underflow instead of inexact when inexact was specified. Fixed. Regtested on x86_64-unknown-linux-gnu, Ok for trunk? frontend ChangeLog: 2011-05-18 Janne Blomqvist <j...@gcc.gnu.org> * gfortran.texi (set_fpe): Update documentation. * invoke.texi (-ffpe-trap): Likewise. * libgfortran.h (GFC_FPE_PRECISION): Rename to GFC_FPE_INEXACT. * options.c (gfc_handle_fpe_trap_option): Handle inexact and make precision an alias for it. libgfortran ChangeLog: 2011-05-18 Janne Blomqvist <j...@gcc.gnu.org> * config/fpu-387.h (set_fpu): Use renamed inexact macro. * config/fpu-aix.h (set_fpu): Clarify error messages, use renamed inexact macro, set TRP_INEXACT for inexact exception instead of TRP_UNDERFLOW. * config/fpu-generic.h (set_fpu): Clarify error messages, use renamed inexact macro. * config/fpu-glibc.h (set_fpu): Likewise. * config/fpu-sysv.h (set_fpu): Likewise. -- Janne Blomqvist
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index 995d9d8..4db506c 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -2718,16 +2718,15 @@ int main (int argc, char *argv[]) @node _gfortran_set_fpe -@subsection @code{_gfortran_set_fpe} --- Set when a Floating Point Exception should be raised +@subsection @code{_gfortran_set_fpe} --- Enable floating point exception traps @fnindex _gfortran_set_fpe @cindex libgfortran initialization, set_fpe @table @asis @item @emph{Description}: -@code{_gfortran_set_fpe} sets the IEEE exceptions for which a -Floating Point Exception (FPE) should be raised. On most systems, -this will result in a SIGFPE signal being sent and the program -being interrupted. +@code{_gfortran_set_fpe} enables floating point exception traps for +the specified exceptions. On most systems, this will result in a +SIGFPE signal being sent and the program being aborted. @item @emph{Syntax}: @code{void _gfortran_set_fpe (int val)} @@ -2738,7 +2737,7 @@ being interrupted. (bitwise or-ed) zero (0, default) no trapping, @code{GFC_FPE_INVALID} (1), @code{GFC_FPE_DENORMAL} (2), @code{GFC_FPE_ZERO} (4), @code{GFC_FPE_OVERFLOW} (8), -@code{GFC_FPE_UNDERFLOW} (16), and @code{GFC_FPE_PRECISION} (32). +@code{GFC_FPE_UNDERFLOW} (16), and @code{GFC_FPE_INEXACT} (32). @end multitable @item @emph{Example}: diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index ab45072..41fee67 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -919,21 +919,31 @@ GNU Fortran compiler itself. This option is deprecated; use @item -ffpe-trap=@var{list} @opindex @code{ffpe-trap=}@var{list} -Specify a list of IEEE exceptions when a Floating Point Exception -(FPE) should be raised. On most systems, this will result in a SIGFPE -signal being sent and the program being interrupted, producing a core -file useful for debugging. @var{list} is a (possibly empty) comma-separated -list of the following IEEE exceptions: @samp{invalid} (invalid floating -point operation, such as @code{SQRT(-1.0)}), @samp{zero} (division by -zero), @samp{overflow} (overflow in a floating point operation), -@samp{underflow} (underflow in a floating point operation), -@samp{precision} (loss of precision during operation) and @samp{denormal} -(operation produced a denormal value). - -Some of the routines in the Fortran runtime library, like -@samp{CPU_TIME}, are likely to trigger floating point exceptions when -@code{ffpe-trap=precision} is used. For this reason, the use of -@code{ffpe-trap=precision} is not recommended. +Specify a list of floating point exception traps to enable. On most +systems, if a floating point exception occurs and the trap for that +exception is enabled, a SIGFPE signal will be sent and the program +being aborted, producing a core file useful for debugging. @var{list} +is a (possibly empty) comma-separated list of the following +exceptions: @samp{invalid} (invalid floating point operation, such as +@code{SQRT(-1.0)}), @samp{zero} (division by zero), @samp{overflow} +(overflow in a floating point operation), @samp{underflow} (underflow +in a floating point operation), @samp{inexact} (loss of precision +during operation), and @samp{denormal} (operation performed on a +denormal value). The first five exceptions correspond to the five +IEEE 754 exceptions, whereas the last one (@samp{denormal}) is not +part of the IEEE 754 standard but is available on some common +architectures such as x86. + +The first three exceptions (@samp{invalid}, @samp{zero}, and +@samp{overflow}) often indicate serious errors, and unless the program +has provisions for dealing with these exceptions, enabling traps for +these three exceptions is probably a good idea. + +Many, if not most, floating point operations incur loss of precision +due to rounding, and hence the @code{ffpe-trap=inexact} is likely to +be uninteresting in practice. + +By default no exception traps are enabled. @item -fno-backtrace @opindex @code{fno-backtrace} diff --git a/gcc/fortran/libgfortran.h b/gcc/fortran/libgfortran.h index 035a32a..b2137bb 100644 --- a/gcc/fortran/libgfortran.h +++ b/gcc/fortran/libgfortran.h @@ -42,7 +42,7 @@ along with GCC; see the file COPYING3. If not see #define GFC_FPE_ZERO (1<<2) #define GFC_FPE_OVERFLOW (1<<3) #define GFC_FPE_UNDERFLOW (1<<4) -#define GFC_FPE_PRECISION (1<<5) +#define GFC_FPE_INEXACT (1<<5) /* Bitmasks for the various runtime checks that can be enabled. */ diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c index 920b95f..4c59bd5 100644 --- a/gcc/fortran/options.c +++ b/gcc/fortran/options.c @@ -492,12 +492,14 @@ static void gfc_handle_fpe_trap_option (const char *arg) { int result, pos = 0, n; + /* precision is a backwards compatibility alias for inexact. */ static const char * const exception[] = { "invalid", "denormal", "zero", "overflow", "underflow", - "precision", NULL }; + "inexact", "precision", NULL }; static const int opt_exception[] = { GFC_FPE_INVALID, GFC_FPE_DENORMAL, GFC_FPE_ZERO, GFC_FPE_OVERFLOW, - GFC_FPE_UNDERFLOW, GFC_FPE_PRECISION, + GFC_FPE_UNDERFLOW, GFC_FPE_INEXACT, + GFC_FPE_INEXACT, 0 }; while (*arg) diff --git a/libgfortran/config/fpu-387.h b/libgfortran/config/fpu-387.h index 2bd9efb..c3e57cb 100644 --- a/libgfortran/config/fpu-387.h +++ b/libgfortran/config/fpu-387.h @@ -110,7 +110,7 @@ void set_fpu (void) if (options.fpe & GFC_FPE_ZERO) cw &= ~_FPU_MASK_ZM; if (options.fpe & GFC_FPE_OVERFLOW) cw &= ~_FPU_MASK_OM; if (options.fpe & GFC_FPE_UNDERFLOW) cw &= ~_FPU_MASK_UM; - if (options.fpe & GFC_FPE_PRECISION) cw &= ~_FPU_MASK_PM; + if (options.fpe & GFC_FPE_INEXACT) cw &= ~_FPU_MASK_PM; asm volatile ("fldcw %0" : : "m" (cw)); @@ -129,7 +129,7 @@ void set_fpu (void) if (options.fpe & GFC_FPE_ZERO) cw_sse &= ~(_FPU_MASK_ZM << 7); if (options.fpe & GFC_FPE_OVERFLOW) cw_sse &= ~(_FPU_MASK_OM << 7); if (options.fpe & GFC_FPE_UNDERFLOW) cw_sse &= ~(_FPU_MASK_UM << 7); - if (options.fpe & GFC_FPE_PRECISION) cw_sse &= ~(_FPU_MASK_PM << 7); + if (options.fpe & GFC_FPE_INEXACT) cw_sse &= ~(_FPU_MASK_PM << 7); asm volatile ("ldmxcsr %0" : : "m" (cw_sse)); } diff --git a/libgfortran/config/fpu-aix.h b/libgfortran/config/fpu-aix.h index 262557b..1348976 100644 --- a/libgfortran/config/fpu-aix.h +++ b/libgfortran/config/fpu-aix.h @@ -43,7 +43,7 @@ set_fpu (void) #endif if (options.fpe & GFC_FPE_DENORMAL) - estr_write ("Fortran runtime warning: IEEE 'denormal number' " + estr_write ("Fortran runtime warning: Floating point 'denormal operand' " "exception not supported.\n"); if (options.fpe & GFC_FPE_ZERO) @@ -70,11 +70,11 @@ set_fpu (void) "exception not supported.\n"); #endif - if (options.fpe & GFC_FPE_PRECISION) -#ifdef TRP_UNDERFLOW - mode |= TRP_UNDERFLOW; + if (options.fpe & GFC_FPE_INEXACT) +#ifdef TRP_INEXACT + mode |= TRP_INEXACT; #else - estr_write ("Fortran runtime warning: IEEE 'loss of precision' " + estr_write ("Fortran runtime warning: IEEE 'inexact' " "exception not supported.\n"); #endif diff --git a/libgfortran/config/fpu-generic.h b/libgfortran/config/fpu-generic.h index 72de91b..b64f90c 100644 --- a/libgfortran/config/fpu-generic.h +++ b/libgfortran/config/fpu-generic.h @@ -35,7 +35,7 @@ set_fpu (void) estr_write ("Fortran runtime warning: IEEE 'invalid operation' " "exception not supported.\n"); if (options.fpe & GFC_FPE_DENORMAL) - estr_write ("Fortran runtime warning: IEEE 'denormal number' " + estr_write ("Fortran runtime warning: Floating point 'denormal operand' " "exception not supported.\n"); if (options.fpe & GFC_FPE_ZERO) estr_write ("Fortran runtime warning: IEEE 'division by zero' " @@ -46,7 +46,7 @@ set_fpu (void) if (options.fpe & GFC_FPE_UNDERFLOW) estr_write ("Fortran runtime warning: IEEE 'underflow' " "exception not supported.\n"); - if (options.fpe & GFC_FPE_PRECISION) - estr_write ("Fortran runtime warning: IEEE 'loss of precision' " + if (options.fpe & GFC_FPE_INEXACT) + estr_write ("Fortran runtime warning: IEEE 'inexact' " "exception not supported.\n"); } diff --git a/libgfortran/config/fpu-glibc.h b/libgfortran/config/fpu-glibc.h index 669b7ad..7bdb7b7 100644 --- a/libgfortran/config/fpu-glibc.h +++ b/libgfortran/config/fpu-glibc.h @@ -49,7 +49,7 @@ void set_fpu (void) #ifdef FE_DENORMAL feenableexcept (FE_DENORMAL); #else - estr_write ("Fortran runtime warning: IEEE 'denormal number' " + estr_write ("Fortran runtime warning: Floating point 'denormal operand' " "exception not supported.\n"); #endif @@ -77,11 +77,11 @@ void set_fpu (void) "exception not supported.\n"); #endif - if (options.fpe & GFC_FPE_PRECISION) + if (options.fpe & GFC_FPE_INEXACT) #ifdef FE_INEXACT feenableexcept (FE_INEXACT); #else - estr_write ("Fortran runtime warning: IEEE 'loss of precision' " + estr_write ("Fortran runtime warning: IEEE 'inexact' " "exception not supported.\n"); #endif } diff --git a/libgfortran/config/fpu-sysv.h b/libgfortran/config/fpu-sysv.h index 4770089..8838f13 100644 --- a/libgfortran/config/fpu-sysv.h +++ b/libgfortran/config/fpu-sysv.h @@ -42,7 +42,7 @@ set_fpu (void) #ifdef FP_X_DNML cw |= FP_X_DNML; #else - estr_write ("Fortran runtime warning: IEEE 'denormal number' " + estr_write ("Fortran runtime warning: Floating point 'denormal operand' " "exception not supported.\n"); #endif @@ -70,11 +70,11 @@ set_fpu (void) "exception not supported.\n"); #endif - if (options.fpe & GFC_FPE_PRECISION) + if (options.fpe & GFC_FPE_INEXACT) #ifdef FP_X_IMP cw |= FP_X_IMP; #else - estr_write ("Fortran runtime warning: IEEE 'loss of precision' " + estr_write ("Fortran runtime warning: IEEE 'inexact' " "exception not supported.\n"); #endif