diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2019-01-30 16:04:06 +0100 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2019-01-30 16:04:06 +0100 |
commit | de0c04f99c561d71a97ad3e89c09027c1815d804 (patch) | |
tree | b76ed6ffe7feae8d614585591f75d89566fc0eb2 /libgfortran | |
parent | 83a67c0cd7fd11f6ca6a88d2e7db594ef7449454 (diff) |
re PR fortran/88678 (Many gfortran.dg/ieee/ieee_X.f90 test cases fail starting with r267465)
PR fortran/88678
* config/fpu-glibc.h (set_fpu_trap_exceptions): Clear stalled
exception flags before changing trap mode. Optimize to call
feenableexcept and fedisableexcept only once.
From-SVN: r268392
Diffstat (limited to 'libgfortran')
-rw-r--r-- | libgfortran/ChangeLog | 7 | ||||
-rw-r--r-- | libgfortran/config/fpu-glibc.h | 32 |
2 files changed, 27 insertions, 12 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 2a604a5959c..87fc2d6a38c 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,10 @@ +2019-01-30 Uroš Bizjak <ubizjak@gmail.com> + + PR fortran/88678 + * config/fpu-glibc.h (set_fpu_trap_exceptions): Clear stalled + exception flags before changing trap mode. Optimize to call + feenableexcept and fedisableexcept only once. + 2019-01-28 Sebastian Huber <sebastian.huber@embedded-brains.de> * io/async.c (init_adv_cond): Use __GTHREAD_COND_INIT_FUNCTION(). diff --git a/libgfortran/config/fpu-glibc.h b/libgfortran/config/fpu-glibc.h index c24bb6cbcd9..9abdfd95ee3 100644 --- a/libgfortran/config/fpu-glibc.h +++ b/libgfortran/config/fpu-glibc.h @@ -39,48 +39,56 @@ _Static_assert (sizeof(fenv_t) <= (size_t) GFC_FPE_STATE_BUFFER_SIZE, void set_fpu_trap_exceptions (int trap, int notrap) { + int mode_set = 0, mode_clr = 0; + #ifdef FE_INVALID if (trap & GFC_FPE_INVALID) - feenableexcept (FE_INVALID); + mode_set |= FE_INVALID; if (notrap & GFC_FPE_INVALID) - fedisableexcept (FE_INVALID); + mode_clr |= FE_INVALID; #endif /* Some glibc targets (like alpha) have FE_DENORMAL, but not many. */ #ifdef FE_DENORMAL if (trap & GFC_FPE_DENORMAL) - feenableexcept (FE_DENORMAL); + mode_set |= FE_DENORMAL; if (notrap & GFC_FPE_DENORMAL) - fedisableexcept (FE_DENORMAL); + mode_clr |= FE_DENORMAL; #endif #ifdef FE_DIVBYZERO if (trap & GFC_FPE_ZERO) - feenableexcept (FE_DIVBYZERO); + mode_set |= FE_DIVBYZERO; if (notrap & GFC_FPE_ZERO) - fedisableexcept (FE_DIVBYZERO); + mode_clr |= FE_DIVBYZERO; #endif #ifdef FE_OVERFLOW if (trap & GFC_FPE_OVERFLOW) - feenableexcept (FE_OVERFLOW); + mode_set |= FE_OVERFLOW; if (notrap & GFC_FPE_OVERFLOW) - fedisableexcept (FE_OVERFLOW); + mode_clr |= FE_OVERFLOW; #endif #ifdef FE_UNDERFLOW if (trap & GFC_FPE_UNDERFLOW) - feenableexcept (FE_UNDERFLOW); + mode_set |= FE_UNDERFLOW; if (notrap & GFC_FPE_UNDERFLOW) - fedisableexcept (FE_UNDERFLOW); + mode_clr |= FE_UNDERFLOW; #endif #ifdef FE_INEXACT if (trap & GFC_FPE_INEXACT) - feenableexcept (FE_INEXACT); + mode_set |= FE_INEXACT; if (notrap & GFC_FPE_INEXACT) - fedisableexcept (FE_INEXACT); + mode_clr |= FE_INEXACT; #endif + + /* Clear stalled exception flags. */ + feclearexcept (FE_ALL_EXCEPT); + + feenableexcept (mode_set); + fedisableexcept (mode_clr); } |