about summary refs log tree commit diff
path: root/math
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2023-10-24 08:37:15 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2023-12-19 15:12:38 -0300
commit47a9eeb9ba72fd30766bdf4faa7d46b8ca33a7fd (patch)
tree4ca5baa3c7cee9c6e40b0bfc583d8c0d2e3ccbe4 /math
parentecb1e7220ddc7a4845bbd1b6fd7fcf17aba566bd (diff)
downloadglibc-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.c26
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>