From patchwork Wed May 18 20:12:16 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janne Blomqvist X-Patchwork-Id: 96222 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id DD523B6EE8 for ; Thu, 19 May 2011 06:12:43 +1000 (EST) Received: (qmail 32756 invoked by alias); 18 May 2011 20:12:40 -0000 Received: (qmail 32727 invoked by uid 22791); 18 May 2011 20:12:35 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, RFC_ABUSE_POST, TW_BG X-Spam-Check-By: sourceware.org Received: from mail-px0-f172.google.com (HELO mail-px0-f172.google.com) (209.85.212.172) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 18 May 2011 20:12:17 +0000 Received: by pxi6 with SMTP id 6so1515607pxi.17 for ; Wed, 18 May 2011 13:12:16 -0700 (PDT) MIME-Version: 1.0 Received: by 10.68.30.73 with SMTP id q9mr3124714pbh.431.1305749536489; Wed, 18 May 2011 13:12:16 -0700 (PDT) Received: by 10.68.54.105 with HTTP; Wed, 18 May 2011 13:12:16 -0700 (PDT) Date: Wed, 18 May 2011 23:12:16 +0300 Message-ID: Subject: [Patch, fortran] Update documentation and error messages for -ffpe-trap From: Janne Blomqvist To: GCC Patches , Fortran List Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 * 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 * 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. 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