autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

New macro AC_FC_FPE_TRAP for Fortran FP Exception handling.


From: Ralf Wildenhues
Subject: New macro AC_FC_FPE_TRAP for Fortran FP Exception handling.
Date: Sun, 27 Feb 2011 17:37:27 +0100
User-agent: Mutt/1.5.20 (2010-08-04)

This patch is still in somewhat of an alpha stage.  The new macro is
probably overly complex (and I'm not sure whether it's best to handle
the first argument at configure time, or earlier at autoconf time in
m4), and the test is too strict so that it fails on most systems.

The latter has two reasons (I think): my understanding of what causes
an FP exception is flawed, and both hardware and compilers and system
environments are not up to the task of supporting all the exceptions
(yet).  Help is appreciated.

And I'm sure I'm mixing elements from various Fortran standards again
...

Thanks,
Ralf

    New macro AC_FC_FPE_TRAP for Fortran FP Exception handling.
    
    * lib/autoconf/fortran.m4 (AC_FC_FPE_TRAP): New macro.
    * tests/fortran.at (AC_FC_FPE_TRAP): New test.
    Prompted by report from Eve-Marie Devaliere.

diff --git a/lib/autoconf/fortran.m4 b/lib/autoconf/fortran.m4
index 338c51d..32efdf6 100644
--- a/lib/autoconf/fortran.m4
+++ b/lib/autoconf/fortran.m4
@@ -1477,3 +1477,140 @@ else
 fi
 AC_LANG_POP([Fortran])dnl
 ])# AC_FC_IMPLICIT_NONE
+
+
+# AC_FC_FPE_TRAP([EXCEPTION-LIST], [ACTION-IF-SUCCESS],
+#                        [ACTION-IF-FAILURE = FAILURE])
+# -----------------------------------------------------
+# Look for a compiler flag to turn on FPE exceptions for the IEEE exceptions
+# listed in EXCEPTION-LIST.  Run ACTION-IF-SUCCESS (defaults to nothing) if
+# successful, and ACTION-IF-FAILURE (defaults to failing with an error message)
+# if not.  EXCEPTION-LIST is a comma-separated list of exceptions from the
+# following list: none, all, common, overflow, zero, invalid, underflow,
+# precision, denormal.  'common' denotes the common setting of enabling
+# overflow, divide by zero, and invalid.
+# Prepend `no-' to the exception in order to turn off the respective exception.
+#
+# Known flags:
+# GCC: -ffpe-trap=overflow,zero,invalid,underflow,precision,denormal
+# Intel: -fpe 0 -fpe 1 -fpe 3
+# Portland: -Ktrap=ovf,divz[,inv,unf,inexact,denorm,fp]  (fp == inv,divz,ovf)
+# HP: +FP[V][Z][O][U][I][D]
+#   (upper-case enables, lower-case disables
+#    invalid fp ops, divide by zero, overflow, underflow, inexact)
+# Lahey: -[n]trap [d][i][o][u]  (divide-by-zero, invalid op. overflow, 
underflow)
+# IBM: -qflttrap=zerodivide:enable -qsigtrap
+#      -qnoflttrap
+#       (zerodivide, underflow, overflow, invalid, inexact, enable,
+#       imprecise, nanq)
+#       -qflttrap without suboptions is equivalent to
+#       -qflttrap=inv:inex:ov:und:zero
+#       -qsigtrap
+# Sun/Oracle: -ftrap=%all,no%inexact -ftrap=common
+#              %all, %none, common, [no%]invalid, [no%]overflow, 
[no%]underflow,
+#              %[no%]division, [no%]inexact.
+#             -ftrap=common is a macro for -ftrap=invalid,overflow,division.
+# Absoft: -TENV:simd_[idzoup]mask{=off}
+#         -trap={INVALID,DIVBYZERO,OVERFLOW,UNDERFLOW,INEXACT,ALL}[,...]
+# SGI: -trapuv
+# MIPS: TRAP_FPE environment variable
+# NAGware: -ieee={full,nonstd,stop}, -nan
+# Compaq: -fpe -fpe<x>
+AC_DEFUN([AC_FC_FPE_TRAP],
+[AC_LANG_PUSH([Fortran])dnl
+m4_pushdef([fpe_traps], [m4_default([$1], [common])])dnl
+AC_CACHE_CHECK([for Fortran flag to set FPE traps fpe_traps],
+               [ac_cv_fc_fpe_trap],
+[ac_cv_fc_fpe_trap=unknown
+ac_fc_fpe_trap_FCFLAGS_save=$FCFLAGS
+# Table consisting of:
+# - option name,
+# - option-argument separator,
+# - argument separator,
+# - option for no traps,
+# - option for all traps,
+# - option for common traps,
+# - trap names for overflow, division by zero, invalid, underflow, precision,
+#   denormal, interleaved with negated values.
+# The table is eval'ed to allow to enter white space and empty arguments.
+m4_define([_AC_FC_FPE_FLAGS],
+  [overflow zero invalid underflow precision denormal])dnl
+ac_fc_fpe_flags='_AC_FC_FPE_FLAGS'
+for ac_fc_flag_table in \
+'-ffpe-trap= , "" 
-ffpe-trap=overflow,zero,invalid,underflow,precision,denormal \
+  -ffpe-trap=overflow,zero,invalid \
+  overflow zero invalid underflow precision denormal "" "" "" "" "" ""' \
+'"" "" "-fpe 1" "-fpe 3" "-fpe 0" "" "" "" "" "" "" "" "" "" "" "" ""' \
+'-Ktrap= , "" -Ktrap=ovf,divz,inv,unf,inexact,denorm -Ktrap=ovf,divz,inv \
+  ovf divz inv unf inexact denorm "" "" "" "" "" ""' \
+'"+FP " "" "+FP ozvuid" "+FP OZVUID" "+FP VZO" O Z V U I D o z v u i d' \
+'-ftrap= , -ftrap=%none -ftrap=%all -ftrap=common \
+  overflow division invalid underflow inexact "" \
+  no%overflow no%division no%invalid no%underflow no%inexact ""' \
+'-qflttrap=en: : -qnoflttrap -qflttrap=ov:zero:inv:und:inex:en 
-qflttrap=inv:ov:zero:en \
+  ov zero inv und inex "" "" "" "" "" "" ""' \
+'"-trap " "" "-trap diou" -ntrap "-trap dio" o d i u "" "" "" "" "" "" "" ""' \
+'-trap= , "" -trap=ALL "" \
+  OVERFLOW DIVBYZERO INVALID UNDERFLOW INEXACT "" "" "" "" "" "" ""' \
+'-TENV: : "" -TENV:X=3 -TENV:simd_omask=ON:simd_imask=ON:simd_zmask=ON \
+  simd_omask=ON simd_zmask=ON simd_imask=ON simd_umask=ON simd_pmask=ON 
simd_dmask=ON \
+  simd_omask=OFF simd_zmask=OFF simd_imask=OFF simd_umask=OFF simd_pmask=OFF 
simd_dmask=OFF' \
+'"" "" "" -ieee=full -ieee=nonstd "" "" "" "" "" "" "" "" "" "" "" ""'
+do
+  eval set X "$ac_fc_flag_table"
+  shift
+  ac_flag= ac_sep=$[]1 ac_sep2=$[]2
+  shift; shift
+  ac_fc_fpe_none=$[]1 ac_fc_fpe_all=$[]2 ac_fc_fpe_common=$[]3
+  shift; shift; shift
+  for ac_pfx in '' no_; do
+    for ac_fc_fpe in $ac_fc_fpe_flags; do
+      eval ac_fc_fpe_$ac_pfx$ac_fc_fpe=$[]1
+      shift
+    done
+  done
+
+  ac_save_IFS=$IFS
+  IFS=' ,:'
+  ac_options="fpe_traps"
+  for ac_option in $ac_options
+  do
+    IFS=$ac_save_IFS
+    ac_add=
+    ac_negate=false
+    case $ac_option in #(
+    none) ac_flag=$ac_fc_fpe_none; break ;; #(
+    all)  ac_flag=$ac_fc_fpe_all; break ;; #(
+m4_foreach_w([flag], _AC_FC_FPE_FLAGS, [dnl
+    ]flag[) ac_add=$ac_fc_fpe_][[]]flag[ ;; #(
+    no-]flag[) ac_add=$ac_fc_fpe_no_][[]]flag[ ;; #(
+])dnl
+    esac #)
+    if test -n "$ac_add"; then
+      ac_flag=$ac_flag$ac_sep$ac_add
+      ac_sep=$ac_sep2
+    fi
+  done
+  IFS=$ac_save_IFS
+
+  FCFLAGS="$ac_fc_fpe_trap_FCFLAGS_save $ac_flag"
+  AC_LINK_IFELSE([[
+      program main
+      end]],
+    [ac_cv_fc_fpe_trap=$ac_flag; break])
+done
+rm -f conftest$ac_exeext conftest.err conftest.$ac_objext conftest.$ac_ext
+FCFLAGS=$ac_fc_fpe_trap_FCFLAGS_save
+])
+if test "x$ac_cv_fc_fpe_trap" = xunknown; then
+  m4_default([$3],
+             [AC_MSG_ERROR([no Fortran flag for FPE exceptions found], 77)])
+else
+  if test "x$ac_cv_fc_fpe_trap" != xnone; then
+    FCFLAGS="$FCFLAGS $ac_cv_fc_fpe_trap"
+  fi
+  $2
+fi
+AC_LANG_POP([Fortran])dnl
+m4_popdef([fpe_traps])dnl
+])# AC_FC_FPE_TRAP
diff --git a/tests/fortran.at b/tests/fortran.at
index c4dd68e..25b6ad0 100644
--- a/tests/fortran.at
+++ b/tests/fortran.at
@@ -989,3 +989,85 @@ AT_CHECK([./prog || exit 1], [1], [ignore], [ignore])
 AT_CHECK([$MAKE clean], [], [ignore], [ignore])
 
 AT_CLEANUP
+
+
+## --------------- ##
+## AC_FC_FPE_TRAP. ##
+## --------------- ##
+
+AT_SETUP([AC_FC_FPE_TRAP])
+
+AT_DATA([Makefile.in],
address@hidden@: address@hidden@
+       @FC@ @FCFLAGS@ -o $@ address@hidden@ @LIBS@
+
+.SUFFIXES: .f address@hidden@
address@hidden@:
+       @FC@ @FCFLAGS@ -c @FCFLAGS_f@ $<
+
+clean:
+       rm -f address@hidden@ address@hidden@
+]])
+
+AT_DATA_AUTOCONF([configure.act],
+[[AC_INIT
+AC_PROG_FC
+AC_FC_SRCEXT([f])
+AC_FC_FPE_TRAP([FLAG])
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+]])
+
+: "${MAKE=make}"
+for flag in none overflow zero invalid underflow precision denormal \
+           "no-overflow, zero, no-invalid, underflow, precision, no-denormal"
+do
+  sed "s/FLAG/$flag/" configure.act > configure.ac
+  AT_CHECK_AUTOCONF
+  AT_CHECK_CONFIGURE
+
+  expstatus=1
+  case $flag in
+  none) test= expstatus=0 ;;
+  all) test='
+      real :: x = 1.0
+      print *, sqrt(-1.0*x)' ;;
+  overflow) test='
+      double precision x = 1.E20
+      x = x * x
+      x = x * x
+      x = x * x
+      x = x * x
+      x = x * x
+      print *, x*x' ;;
+  zero) test='
+      real :: x = 0.0
+      print *, 1.0/x' ;;
+  invalid) test='
+      real :: x = 1.0
+      print *, sqrt(-1.0*x)' ;;
+  underflow) test='
+      double precision x = 1.E-20
+      x = x * x
+      x = x * x
+      x = x * x
+      x = x * x
+      x = x * x
+      print *, x*x' ;;
+  precision) test='
+      real :: x = 3.0
+      x = 2.0 / x' ;;
+  denormal) test= expstatus=0 ;;
+  esac
+  cat >prog.f <<EOF
+      program main
+$test
+      end program
+EOF
+
+  AT_CHECK([$MAKE], [], [ignore], [ignore])
+  AT_CHECK([./prog || exit 1], [$expstatus], [ignore], [ignore])
+  AT_CHECK([$MAKE clean], [], [ignore], [ignore])
+done
+
+AT_CLEANUP



reply via email to

[Prev in Thread] Current Thread [Next in Thread]