This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH v2][PR libgfortran/78314] Fix ieee_support_halting
- From: Szabolcs Nagy <szabolcs dot nagy at arm dot com>
- To: FX <fxcoudert at gmail dot com>
- Cc: <nd at arm dot com>, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>, FranC'ois-Xavier Coudert <fxcoudert at gcc dot gnu dot org>, Jerry DeLisle <jvdelisle at gcc dot gnu dot org>, GCC-Fortran-ML <fortran at gcc dot gnu dot org>
- Date: Wed, 16 Nov 2016 16:53:10 +0000
- Subject: [PATCH v2][PR libgfortran/78314] Fix ieee_support_halting
- Authentication-results: sourceware.org; auth=none
- Authentication-results: spf=none (sender IP is ) smtp.mailfrom=Szabolcs dot Nagy at arm dot com;
- Nodisclaimer: True
- References: <582B3331.30402@arm.com> <92DFB085-F0FF-4B30-B6BB-B10E598B6030@gmail.com> <582B39DB.80302@arm.com> <24AAE5F7-890A-4154-8BED-478E3C994A11@gmail.com>
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
ieee_support_halting only checked the availability of status
flags, not trapping support. On some targets the later can
only be checked at runtime: feenableexcept reports if
enabling traps failed.
So check trapping support by enabling/disabling it.
Updated the test that enabled trapping to check if it is
supported.
Tested on aarch64-linux-gnu and x86_64-linux-gnu.
gcc/testsuite/
2016-11-16 Szabolcs Nagy <szabolcs.nagy@arm.com>
PR libgfortran/78314
* gfortran.dg/ieee/ieee_6.f90: Use ieee_support_halting.
libgfortran/
2016-11-16 Szabolcs Nagy <szabolcs.nagy@arm.com>
PR libgfortran/78314
* config/fpu-glibc.h (support_fpu_trap): Use feenableexcept.
diff --git a/gcc/testsuite/gfortran.dg/ieee/ieee_6.f90 b/gcc/testsuite/gfortran.dg/ieee/ieee_6.f90
index 8fb4f6f..43aa3bf 100644
--- a/gcc/testsuite/gfortran.dg/ieee/ieee_6.f90
+++ b/gcc/testsuite/gfortran.dg/ieee/ieee_6.f90
@@ -9,7 +9,7 @@
implicit none
type(ieee_status_type) :: s1, s2
- logical :: flags(5), halt(5)
+ logical :: flags(5), halt(5), haltworks
type(ieee_round_type) :: mode
real :: x
@@ -18,6 +18,7 @@
call ieee_set_flag(ieee_all, .false.)
call ieee_set_rounding_mode(ieee_down)
call ieee_set_halting_mode(ieee_all, .false.)
+ haltworks = ieee_support_halting(ieee_overflow)
call ieee_get_status(s1)
call ieee_set_status(s1)
@@ -46,7 +47,7 @@
call ieee_get_rounding_mode(mode)
if (mode /= ieee_to_zero) call abort
call ieee_get_halting_mode(ieee_all, halt)
- if ((.not. halt(1)) .or. any(halt(2:))) call abort
+ if ((haltworks .and. .not. halt(1)) .or. any(halt(2:))) call abort
call ieee_set_status(s2)
@@ -58,7 +59,7 @@
call ieee_get_rounding_mode(mode)
if (mode /= ieee_to_zero) call abort
call ieee_get_halting_mode(ieee_all, halt)
- if ((.not. halt(1)) .or. any(halt(2:))) call abort
+ if ((haltworks .and. .not. halt(1)) .or. any(halt(2:))) call abort
call ieee_set_status(s1)
@@ -79,6 +80,6 @@
call ieee_get_rounding_mode(mode)
if (mode /= ieee_to_zero) call abort
call ieee_get_halting_mode(ieee_all, halt)
- if ((.not. halt(1)) .or. any(halt(2:))) call abort
+ if ((haltworks .and. .not. halt(1)) .or. any(halt(2:))) call abort
end
diff --git a/libgfortran/config/fpu-glibc.h b/libgfortran/config/fpu-glibc.h
index 6e505da..8b29a76 100644
--- a/libgfortran/config/fpu-glibc.h
+++ b/libgfortran/config/fpu-glibc.h
@@ -121,7 +121,41 @@ get_fpu_trap_exceptions (void)
int
support_fpu_trap (int flag)
{
- return support_fpu_flag (flag);
+ int exceptions = 0;
+ int old;
+
+ if (!support_fpu_flag (flag))
+ return 0;
+
+#ifdef FE_INVALID
+ if (flag & GFC_FPE_INVALID) exceptions |= FE_INVALID;
+#endif
+
+#ifdef FE_DIVBYZERO
+ if (flag & GFC_FPE_ZERO) exceptions |= FE_DIVBYZERO;
+#endif
+
+#ifdef FE_OVERFLOW
+ if (flag & GFC_FPE_OVERFLOW) exceptions |= FE_OVERFLOW;
+#endif
+
+#ifdef FE_UNDERFLOW
+ if (flag & GFC_FPE_UNDERFLOW) exceptions |= FE_UNDERFLOW;
+#endif
+
+#ifdef FE_DENORMAL
+ if (flag & GFC_FPE_DENORMAL) exceptions |= FE_DENORMAL;
+#endif
+
+#ifdef FE_INEXACT
+ if (flag & GFC_FPE_INEXACT) exceptions |= FE_INEXACT;
+#endif
+
+ old = feenableexcept (exceptions);
+ if (old == -1)
+ return 0;
+ fedisableexcept (exceptions & ~old);
+ return 1;
}