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]

Add rounding mode information to math-tests.h and use it in libm-test.inc


The lists of known testsuite failures for ARM and MIPS include various
tests failing in circumstances when rounding modes or exceptions
support is not available at runtime.

In line with the principle of trying to have zero failures as the
expected testsuite state, this patch adds macros to math-tests.h to
say when testing of a rounding mode should be disabled despite
fesetround succeeding, and makes libm-test.inc use them, with
definitions being added for ARM; similar macros will also be needed to
indicate when support for exceptions is available, and the macros will
need using in other tests.  These macros will also be usable for MIPS,
to describe the situation there where MIPS64 long double (IEEE quad)
is implemented in libgcc using soft-fp without support for exceptions
or rounding modes, even when float and double use hardware floating
point.

(fesetround passing but not properly affecting all types is of course
a bug, but one only fixable in libgcc - by using IFUNC there in the
ARM case to make __aeabi_* use VFP when available at runtime, by using
soft-fp instead of fp-bit in the MIPS case.  Disabling the tests here
is similar to the existing handling of sNaN tests; if the GCC issues
are fixed, the math-tests.h definitions can be made conditional on the
GCC version.  Macros indicating when exception support is expected to
be missing will still be relevant even with fixed libgcc.)

Tested on an affected ARM configuration that the non-default
rounding-mode tests from libm-test.inc are no longer run with this
patch applied.

2013-06-04  Joseph Myers  <joseph@codesourcery.com>

	* sysdeps/generic/math-tests.h (ROUNDING_TESTS_float): New macro.
	(ROUNDING_TESTS_double): Likewise.
	(ROUNDING_TESTS_long_double): Likewise.
	(ROUNDING_TESTS): Likewise.
	* math/libm-test.inc: Include <math-tests.h>.
	(IF_ROUND_INIT_FE_DOWNWARD): Use ROUNDING_TESTS.
	(IF_ROUND_INIT_FE_TONEAREST): Likewise.
	(IF_ROUND_INIT_FE_TOWARDZERO): Likewise.
	(IF_ROUND_INIT_FE_UPWARD): Likewise.

ports/ChangeLog.arm
2013-06-04  Joseph Myers  <joseph@codesourcery.com>

	* sysdeps/arm/math-tests.h: New file.

diff --git a/math/libm-test.inc b/math/libm-test.inc
index 6870d96..ed050cb 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -125,6 +125,7 @@
 #include <string.h>
 #include <argp.h>
 #include <tininess.h>
+#include <math-tests.h>
 
 /* Structure for ulp data for a test, a function, or the real or
    imaginary part of a function.  */
@@ -1085,16 +1086,20 @@ struct test_fFF_11_data
 #define IF_ROUND_INIT_	/* Empty.  */
 #define IF_ROUND_INIT_FE_DOWNWARD		\
   int save_round_mode = fegetround ();		\
-  if (fesetround (FE_DOWNWARD) == 0)
+  if (ROUNDING_TESTS (FLOAT, FE_DOWNWARD)	\
+      && fesetround (FE_DOWNWARD) == 0)
 #define IF_ROUND_INIT_FE_TONEAREST		\
   int save_round_mode = fegetround ();		\
-  if (fesetround (FE_TONEAREST) == 0)
+  if (ROUNDING_TESTS (FLOAT, FE_TONEAREST)	\
+      && fesetround (FE_TONEAREST) == 0)
 #define IF_ROUND_INIT_FE_TOWARDZERO		\
   int save_round_mode = fegetround ();		\
-  if (fesetround (FE_TOWARDZERO) == 0)
+  if (ROUNDING_TESTS (FLOAT, FE_TOWARDZERO)	\
+      && fesetround (FE_TOWARDZERO) == 0)
 #define IF_ROUND_INIT_FE_UPWARD			\
   int save_round_mode = fegetround ();		\
-  if (fesetround (FE_UPWARD) == 0)
+  if (ROUNDING_TESTS (FLOAT, FE_UPWARD)		\
+      && fesetround (FE_UPWARD) == 0)
 #define ROUND_RESTORE_	/* Empty.  */
 #define ROUND_RESTORE_FE_DOWNWARD		\
   fesetround (save_round_mode)
diff --git a/ports/sysdeps/arm/math-tests.h b/ports/sysdeps/arm/math-tests.h
new file mode 100644
index 0000000..6b8e089
--- /dev/null
+++ b/ports/sysdeps/arm/math-tests.h
@@ -0,0 +1,28 @@
+/* Configuration for math tests.  ARM version.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* On systems with VFP support, but where glibc is built for
+   soft-float, the libgcc functions used in libc and libm do not
+   support rounding modes, although fesetround succeeds.  */
+#ifdef __SOFTFP__
+# define ROUNDING_TESTS_float(MODE)	((MODE) == FE_TONEAREST)
+# define ROUNDING_TESTS_double(MODE)	((MODE) == FE_TONEAREST)
+# define ROUNDING_TESTS_long_double(MODE)	((MODE) == FE_TONEAREST)
+#endif
+
+#include_next <math-tests.h>
diff --git a/sysdeps/generic/math-tests.h b/sysdeps/generic/math-tests.h
index da8747a..b1e9fd7 100644
--- a/sysdeps/generic/math-tests.h
+++ b/sysdeps/generic/math-tests.h
@@ -40,3 +40,21 @@
 #ifndef SNAN_TESTS_TYPE_CAST
 # define SNAN_TESTS_TYPE_CAST	1
 #endif
+
+/* Indicate whether to run tests involving a given rounding mode for a
+   given floating-point type, given that fesetround succeeds for that
+   mode.  All are run if fesetround succeeds unless overridden.  */
+#ifndef ROUNDING_TESTS_float
+# define ROUNDING_TESTS_float(MODE)	1
+#endif
+#ifndef ROUNDING_TESTS_double
+# define ROUNDING_TESTS_double(MODE)	1
+#endif
+#ifndef ROUNDING_TESTS_long_double
+# define ROUNDING_TESTS_long_double(MODE)	1
+#endif
+
+#define ROUNDING_TESTS(TYPE, MODE)					\
+  (sizeof (TYPE) == sizeof (float) ? ROUNDING_TESTS_float (MODE)	\
+   : sizeof (TYPE) == sizeof (double) ? ROUNDING_TESTS_double (MODE)	\
+   : ROUNDING_TESTS_long_double (MODE))

-- 
Joseph S. Myers
joseph@codesourcery.com


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