[Top][All Lists]
[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