Message ID | Pine.LNX.4.64.1409171944140.17727@digraph.polyomino.org.uk |
---|---|
State | New |
Headers | show |
On Wed, Sep 17, 2014 at 9:47 PM, Joseph S. Myers <joseph@codesourcery.com> wrote: > The i386 sfp-machine.h defines FP_TRAPPING_EXCEPTIONS in a way that is > always wrong: it treats a set bit as indicating the exception is > trapping, when actually a set bit (both for 387 and SSE floating > point) indicates it is masked, and a clear bit indicates it is > trapping. This patch fixes this bug. > > Bootstrapped with no regressions on x86_64-unknown-linux-gnu. OK to > commit? > > Note to ia64 maintainers: it would be a good idea to add a definition > of FP_TRAPPING_EXCEPTIONS for ia64, and I expect the new test to fail > on ia64 until you do so. > > libgcc: > 2014-09-17 Joseph Myers <joseph@codesourcery.com> > > * config/i386/sfp-machine.h (FP_TRAPPING_EXCEPTIONS): Treat clear > bits not set bits as indicating trapping exceptions. > > gcc/testsuite: > 2014-09-17 Joseph Myers <joseph@codesourcery.com> > > * gcc.dg/torture/float128-exact-underflow.c: New test. My brown paperbag bug :( OK for mainline and release branches. Thanks, Uros.
On Thu, 18 Sep 2014, Uros Bizjak wrote:
> OK for mainline and release branches.
I've omitted ia64 from the targets in the testcase in the release branch
version, given the lack of any definition of FP_TRAPPING_EXCEPTIONS at all
there.
(I think a definition as (~_fcw & 0x3f) should work for ia64, but haven't
tested that.)
Index: gcc/testsuite/gcc.dg/torture/float128-exact-underflow.c =================================================================== --- gcc/testsuite/gcc.dg/torture/float128-exact-underflow.c (revision 0) +++ gcc/testsuite/gcc.dg/torture/float128-exact-underflow.c (revision 0) @@ -0,0 +1,41 @@ +/* Test that exact underflow in __float128 signals the underflow + exception if trapping is enabled, but does not raise the flag + otherwise. */ + +/* { dg-do run { target i?86-*-*gnu* x86_64-*-*gnu* ia64-*-*gnu* } } */ +/* { dg-options "-D_GNU_SOURCE" } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#include <fenv.h> +#include <setjmp.h> +#include <signal.h> +#include <stdlib.h> + +volatile sig_atomic_t caught_sigfpe; +sigjmp_buf buf; + +static void +handle_sigfpe (int sig) +{ + caught_sigfpe = 1; + siglongjmp (buf, 1); +} + +int +main (void) +{ + volatile __float128 a = 0x1p-16382q, b = 0x1p-2q; + volatile __float128 r; + r = a * b; + if (fetestexcept (FE_UNDERFLOW)) + abort (); + if (r != 0x1p-16384q) + abort (); + feenableexcept (FE_UNDERFLOW); + signal (SIGFPE, handle_sigfpe); + if (sigsetjmp (buf, 1) == 0) + r = a * b; + if (!caught_sigfpe) + abort (); + exit (0); +} Index: libgcc/config/i386/sfp-machine.h =================================================================== --- libgcc/config/i386/sfp-machine.h (revision 215323) +++ libgcc/config/i386/sfp-machine.h (working copy) @@ -60,7 +60,7 @@ __sfp_handle_exceptions (_fex); \ } while (0); -#define FP_TRAPPING_EXCEPTIONS ((_fcw >> FP_EX_SHIFT) & FP_EX_ALL) +#define FP_TRAPPING_EXCEPTIONS ((~_fcw >> FP_EX_SHIFT) & FP_EX_ALL) #define FP_ROUNDMODE (_fcw & FP_RND_MASK) #endif