This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Promote a math test for sNaN handling to the top-level.


Hi!

On Sun, 17 Mar 2013 16:25:18 +0100, Andreas Jaeger <aj@suse.com> wrote:
> On 03/05/2013 08:36 PM, Thomas Schwinge wrote:
> > Tested on x86 and x86_64 GNU/Linux natively, and cross-tested for MIPS32
> > O32 GNU/Linux.
> 
> This fails for me while building on x86-64 for x86:
> 
> uild/glibc/x86/resolv:/home/aj/build/glibc/x86/crypt:/home/aj/build/glibc/x86/nptl 
> /home/aj/build/glibc/x86/math/test-snan  > 
> /home/aj/build/glibc/x86/math/test-snan.out
> Didn't expect signal from child: got `Floating point exception'
> make[2]: *** [/home/aj/build/glibc/x86/math/test-snan.out] Error 1

That is the issue around "float vs. integer calling conventions",
discussed in the thread starting at
<http://news.gmane.org/find-root.php?message_id=%3C8762148l9v.fsf%40schwinge.name%3E>.
In short, that is to be expected (given what the compiler is doing), in
particular it is not a regression but rather an issue that has only now
been uncovered by starting to use that testcase, and we'll have to figure
out a way to "XFAIL" such tests in glibc for 32-bit x86 (at least for the
time being).  "XFAIL" in quotes, because there isn't really an XFAIL
mechanism in glibc testing, so instead we'd not run certain tests for
32-bit x86.  How's the following?

On 32-bit x86, disable certain tests involving sNaN values.

	* math/test-snan.c (sNaN_tests): New variable.
	(do_test): Set it.
	(TEST_FUNC): Use it to short-circuit certain tests.
	* sysdeps/i386/fpu/Makefile [$(subdir) = math]
	(CPPFLAGS-test-snan.c): Set.

diff --git math/test-snan.c math/test-snan.c
index 83657ee..79bd6c4 100644
--- math/test-snan.c
+++ math/test-snan.c
@@ -34,6 +34,8 @@ char *dest_address;
 double	value = 123.456;
 double	zero = 0.0;
 
+static int sNaN_tests;
+
 static sigjmp_buf sigfpe_buf;
 
 typedef long double ldouble;
@@ -139,7 +141,8 @@ NAME (void)								      \
       printf (#FLOAT " isnan (sNaN) raised SIGFPE\n");			      \
       errors++;								      \
     } else {								      \
-      check (#FLOAT " isnan (sNaN)", isnan (sNaN_var));			      \
+      check (#FLOAT " isnan (sNaN)",					      \
+             sNaN_tests ? isnan (sNaN_var) : 1);			      \
     }									      \
 									      \
   feclearexcept(FE_ALL_EXCEPT);						      \
@@ -149,7 +152,8 @@ NAME (void)								      \
       printf (#FLOAT " isnan (-sNaN) raised SIGFPE\n");			      \
       errors++;								      \
     } else {								      \
-      check (#FLOAT " isnan (-sNaN)", isnan (minus_sNaN_var));		      \
+      check (#FLOAT " isnan (-sNaN)",					      \
+             sNaN_tests ? isnan (minus_sNaN_var) : 1);			      \
     }									      \
 									      \
   feclearexcept(FE_ALL_EXCEPT);						      \
@@ -179,7 +183,8 @@ NAME (void)								      \
       printf (#FLOAT " isinf (sNaN) raised SIGFPE\n");			      \
       errors++;								      \
     } else {								      \
-      check (#FLOAT " isinf (sNaN)", !isinf (sNaN_var));		      \
+      check (#FLOAT " isinf (sNaN)",					      \
+             sNaN_tests ? !isinf (sNaN_var) : 1);			      \
     }									      \
 									      \
   feclearexcept(FE_ALL_EXCEPT);						      \
@@ -189,7 +194,8 @@ NAME (void)								      \
       printf (#FLOAT " isinf (-sNaN) raised SIGFPE\n");			      \
       errors++;								      \
     } else {								      \
-      check (#FLOAT " isinf (-sNaN)", !isinf (minus_sNaN_var));		      \
+      check (#FLOAT " isinf (-sNaN)",					      \
+             sNaN_tests ? !isinf (minus_sNaN_var) : 1);			      \
     }									      \
 									      \
   feclearexcept(FE_ALL_EXCEPT);						      \
@@ -219,7 +225,8 @@ NAME (void)								      \
       printf (#FLOAT " isfinite (sNaN) raised SIGFPE\n");		      \
       errors++;								      \
     } else {								      \
-      check (#FLOAT " isfinite (sNaN)", !isfinite (sNaN_var));		      \
+      check (#FLOAT " isfinite (sNaN)",					      \
+             sNaN_tests ? !isfinite (sNaN_var) : 1);			      \
     }									      \
 									      \
   feclearexcept(FE_ALL_EXCEPT);						      \
@@ -229,7 +236,8 @@ NAME (void)								      \
       printf (#FLOAT " isfinite (-sNaN) raised SIGFPE\n");		      \
       errors++;								      \
     } else {								      \
-      check (#FLOAT " isfinite (-sNaN)", !isfinite (minus_sNaN_var));	      \
+      check (#FLOAT " isfinite (-sNaN)",				      \
+             sNaN_tests ? !isfinite (minus_sNaN_var) : 1);		      \
     }									      \
 									      \
   feclearexcept(FE_ALL_EXCEPT);						      \
@@ -259,7 +267,8 @@ NAME (void)								      \
       printf (#FLOAT " isnormal (sNaN) isnormal SIGFPE\n");		      \
       errors++;								      \
     } else {								      \
-      check (#FLOAT " isnormal (sNaN)", !isnormal (sNaN_var));		      \
+      check (#FLOAT " isnormal (sNaN)",					      \
+             sNaN_tests ? !isnormal (sNaN_var) : 1);			      \
     }									      \
 									      \
   feclearexcept(FE_ALL_EXCEPT);						      \
@@ -269,7 +278,8 @@ NAME (void)								      \
       printf (#FLOAT " isnormal (-sNaN) raised SIGFPE\n");		      \
       errors++;								      \
     } else {								      \
-      check (#FLOAT " isnormal (-sNaN)", !isnormal (minus_sNaN_var));	      \
+      check (#FLOAT " isnormal (-sNaN)",				      \
+             sNaN_tests ? !isnormal (minus_sNaN_var) : 1);		      \
     }									      \
 									      \
   feclearexcept(FE_ALL_EXCEPT);						      \
@@ -299,7 +309,8 @@ NAME (void)								      \
       printf (#FLOAT " fpclassify (sNaN) isnormal SIGFPE\n");		      \
       errors++;								      \
     } else {								      \
-      check (#FLOAT " fpclassify (sNaN)", fpclassify (sNaN_var) == FP_NAN);   \
+      check (#FLOAT " fpclassify (sNaN)",				      \
+             sNaN_tests ? fpclassify (sNaN_var) == FP_NAN : 1);		      \
     }									      \
 									      \
   feclearexcept(FE_ALL_EXCEPT);						      \
@@ -310,7 +321,7 @@ NAME (void)								      \
       errors++;								      \
     } else {								      \
       check (#FLOAT " fpclassify (-sNaN)",				      \
-	     fpclassify (minus_sNaN_var) == FP_NAN);			      \
+	     sNaN_tests ? fpclassify (minus_sNaN_var) == FP_NAN : 1);	      \
     }									      \
 									      \
   fesetenv(&saved_fenv); /* restore saved fenv */			      \
@@ -326,6 +337,10 @@ TEST_FUNC (ldouble_test, ldouble, l)
 static int
 do_test (void)
 {
+#ifndef NO_SNAN_TESTS
+  sNaN_tests = 1;
+#endif
+
   float_test();
   double_test();
 #ifndef NO_LONG_DOUBLE
diff --git sysdeps/i386/fpu/Makefile sysdeps/i386/fpu/Makefile
index 1309b64..c3fbd94 100644
--- sysdeps/i386/fpu/Makefile
+++ sysdeps/i386/fpu/Makefile
@@ -1,3 +1,11 @@
 ifeq ($(subdir),math)
 $(objpfx)libm.so: $(elfobjdir)/ld.so
 endif
+
+# On 32-bit x86, GCC is happy to use FPU load instructions for sNaN values, and
+# loading a float or double sNaN value will already raise an INVALID exception
+# as well as turn the sNaN into a qNan, rendering certain tests infeasible in
+# this scenario.
+ifeq ($(subdir),math)
+CPPFLAGS-test-snan.c += -DNO_SNAN_TESTS
+endif


GrÃÃe,
 Thomas

Attachment: pgp00000.pgp
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]