autoconf-patches
[Top][All Lists]
Advanced

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

Re: New macro AC_FC_FPE_TRAP for Fortran FP Exception handling.


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

* Ralf Wildenhues wrote on Sun, Feb 27, 2011 at 05:37:27PM CET:
> 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.

Updated patch with weaker test, passes for me with gfortran 4.3.5,
Intel, XL, Sun on GNU/Linux, and only fails the autogenerated test with
Sun on Solaris because a core file is generated.

Sorry for the noise.

Cheers,
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 104ebe7..0f2564b 100644
--- a/lib/autoconf/fortran.m4
+++ b/lib/autoconf/fortran.m4
@@ -1477,3 +1477,175 @@ 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: -fpe0 -fpe1 -fpe3
+# 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.
+# The Intel entry comes first since the compiler ignores unknown 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 \
+'"" "" -fpe1 -fpe3 -fpe0 "" "" "" "" "" "" "" "" "" "" "" ""' \
+'-ffpe-trap= , "" 
-ffpe-trap=overflow,zero,invalid,underflow,precision,denormal \
+  -ffpe-trap=overflow,zero,invalid \
+  overflow zero invalid underflow precision denormal "" "" "" "" "" ""' \
+'-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 ;; #(
+    common) ac_flag=$ac_fc_fpe_common; 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
+
+  if test -z "$ac_flag"; then
+    case $ac_option in #(
+    none) ;; #(
+    *) continue ;;
+    esac
+  fi
+
+  FCFLAGS="$ac_fc_fpe_trap_FCFLAGS_save $ac_flag"
+  AC_LINK_IFELSE([[
+      program main
+      real zero, small, large, minusone, three
+      minusone = -1.0
+      zero = 0.0
+      three = 3.0
+      small = 1.E-20
+      large = 1.E20
+      small = small * small
+      small = small * small
+      small = small * small
+      small = small * small
+      large = large * large
+      large = large * large
+      large = large * large
+      large = large * large
+      print *, small
+      print *, large
+      print *, 1.0 / zero
+      print *, sqrt(minusone)
+      print *, 2.0 / three
+      end]],
+    [# If we can run the program, require failure at run time.
+     # In cross-compiling mode, we rely on the compiler not accepting
+     # unknown options.
+     AS_IF([test "$cross_compiling" = yes || test "x$ac_option" = xnone],
+       [ac_cv_fc_fpe_trap=$ac_flag; break],
+       [AS_IF([_AC_DO_TOKENS(./conftest$ac_exeext >/dev/null)],
+          [],
+          [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..4d6377a 100644
--- a/tests/fortran.at
+++ b/tests/fortran.at
@@ -989,3 +989,97 @@ 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 common all 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 ;;
+  common) test='
+      real x
+      x = 0.0
+      print *, 1.0/x' ;;
+  all) test='
+      real x
+      x = 0.0
+      print *, 1.0/x' ;;
+  overflow) test='
+      double precision x
+      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
+      x = 0.0
+      print *, 1.0/x' ;;
+  invalid) test='
+      real x
+      x = -1.0
+      print *, sqrt(x)' ;;
+  underflow) test='
+      double precision x
+      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
+      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])
+  # Some gfortran versions do not implement underflow and invalid yet.
+  # See <http://gcc.gnu.org/PR29383>.
+  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]