diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2023-10-24 08:37:15 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2023-12-19 15:12:38 -0300 |
commit | 47a9eeb9ba72fd30766bdf4faa7d46b8ca33a7fd (patch) | |
tree | 4ca5baa3c7cee9c6e40b0bfc583d8c0d2e3ccbe4 /math | |
parent | ecb1e7220ddc7a4845bbd1b6fd7fcf17aba566bd (diff) | |
download | glibc-47a9eeb9ba72fd30766bdf4faa7d46b8ca33a7fd.tar.gz glibc-47a9eeb9ba72fd30766bdf4faa7d46b8ca33a7fd.tar.xz glibc-47a9eeb9ba72fd30766bdf4faa7d46b8ca33a7fd.zip |
i686: Do not raise exception traps on fesetexcept (BZ 30989)
According to ISO C23 (7.6.4.4), fesetexcept is supposed to set floating-point exception flags without raising a trap (unlike feraiseexcept, which is supposed to raise a trap if feenableexcept was called with the appropriate argument). The flags can be set in the 387 unit or in the SSE unit. To set a flag, it is sufficient to do it in the SSE unit, because that is guaranteed to not trap. However, on i386 CPUs that have only a 387 unit, set the flags in the 387, as long as this cannot trap. Checked on i686-linux-gnu. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'math')
-rw-r--r-- | math/test-fesetexcept-traps.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/math/test-fesetexcept-traps.c b/math/test-fesetexcept-traps.c index 7efcd0343a..9e2023962b 100644 --- a/math/test-fesetexcept-traps.c +++ b/math/test-fesetexcept-traps.c @@ -19,6 +19,7 @@ #include <fenv.h> #include <stdio.h> #include <math-tests.h> +#include <math-barriers.h> static int do_test (void) @@ -41,12 +42,32 @@ do_test (void) /* Verify fesetexcept does not cause exception traps. For architectures where setting the exception might result in traps the function should - return a nonzero value. */ + return a nonzero value. + Also check if the function does not alter the exception mask. */ ret = fesetexcept (FE_ALL_EXCEPT); _Static_assert (!(EXCEPTION_SET_FORCES_TRAP && !EXCEPTION_TESTS(float)), "EXCEPTION_SET_FORCES_TRAP only makes sense if the " "architecture suports exceptions"); + { + int exc_before = fegetexcept (); + ret = fesetexcept (FE_ALL_EXCEPT); + int exc_after = fegetexcept (); + if (exc_before != exc_after) + { + puts ("fesetexcept (FE_ALL_EXCEPT) changed the exceptions mask"); + return 1; + } + } + + /* Execute some floating-point operations, since on some CPUs exceptions + triggers a trap only at the next floating-point instruction. */ + volatile double a = 1.0; + volatile double b = a + a; + math_force_eval (b); + volatile long double al = 1.0L; + volatile long double bl = al + al; + math_force_eval (bl); if (ret == 0) { @@ -72,5 +93,4 @@ do_test (void) return result; } -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" +#include <support/test-driver.c> |