summary refs log tree commit diff
path: root/math
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2018-05-18 17:30:18 +0000
committerJoseph Myers <joseph@codesourcery.com>2018-05-18 17:30:18 +0000
commit7c67e6e8b9815d18f548f9c54444adaef17c0a6e (patch)
treef81a8d93bff75768df72b97e44893d75cf5dc664 /math
parentebc129fd17e8110eb76fb5ebdbb2dc395507ceeb (diff)
downloadglibc-7c67e6e8b9815d18f548f9c54444adaef17c0a6e.tar.gz
glibc-7c67e6e8b9815d18f548f9c54444adaef17c0a6e.tar.xz
glibc-7c67e6e8b9815d18f548f9c54444adaef17c0a6e.zip
Split test-tgmath3 by function.
It has been noted that test-tgmath3 is slow to compile, and to link on
some systems
<https://sourceware.org/ml/libc-alpha/2018-02/msg00477.html>, because
of the size of the test.

I'm working on tgmath.h support for the TS 18661-1 / 18661-3 functions
that round their results to a narrower type.  For the functions
already present in glibc, this wouldn't make test-tgmath3 much bigger,
because those functions only have two arguments.  For the narrowing
versions of fma (for which I've not yet added the functions to glibc),
however, it would result in many configurations building tests of the
type-generic macros f32fma, f64fma, f32xfma, f64xfma, each with 21
possible types for each of three arguments (float, double, long double
aren't valid argument types for these macros when they return a
_FloatN / _FloatNx type), so substantially increasing the size of the
testcase.

To avoid further increasing the size of a single test when adding the
type-generic narrowing fma macros, this patch arranges for the
test-tgmath3 tests to be run separately for each function tested.  The
fma tests are still by far the largest (next is pow, as that has two
arguments that can be real or complex; after that, the two-argument
real-only functions), but each type-generic fma macro for a different
return type would end up with its tests being run separately, rather
than increasing the size of a single test.

To avoid accidentally missing testing a macro because
gen-tgmath-tests.py supports testing it but the makefile fails to call
it for that function, a test is also added that verifies that the
lists of macros in the makefile and gen-tgmath-tests.py agree.

Tested for x86_64.

	* math/gen-tgmath-tests.py: Import sys.
	(Tests.__init__): Initialize macros_seen.
	(Tests.add_tests): Add macro to macros_seen.  Only generate tests
	if requested to do so for this macro.
	(Tests.add_all_tests): Take argument for macro for which to
	generate tests.
	(Tests.check_macro_list): New function.
	(main): Handle check-list argument and argument specifying macro
	for which to generate tests.
	* math/Makefile [PYTHON] (tgmath3-macros): New variable.
	[PYTHON] (tgmath3-macro-tests): Likewise.
	[PYTHON] (tests): Add $(tgmath3-macro-tests) not test-tgmath3.
	[PYTHON] (generated): Add $(addsuffix .c,$(tgmath3-macro-tests))
	not test-tgmath3.c.
	[PYTHON] (CFLAGS-test-tgmath3.c): Remove.
	[PYTHON] ($(tgmath3-macro-tests:%=$(objpfx)%.o): Add -fno-builtin
	to CFLAGS.
	[PYTHON] ($(objpfx)test-tgmath3.c): Replace rule by....
	[PYTHON] ($(foreach
	m,$(tgmath3-macros),$(objpfx)test-tgmath3-$(m).c): ... this.  New
	rule.
	[PYTHON] (tests-special): Add
	$(objpfx)test-tgmath3-macro-list.out.
	[PYTHON] ($(objpfx)test-tgmath3-macro-list.out): New rule.
Diffstat (limited to 'math')
-rw-r--r--math/Makefile32
-rwxr-xr-xmath/gen-tgmath-tests.py34
2 files changed, 55 insertions, 11 deletions
diff --git a/math/Makefile b/math/Makefile
index 23574f5e09..ea141cbf99 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -350,12 +350,32 @@ $(libm-test-c-narrow-obj): $(objpfx)libm-test%.c: libm-test%.inc \
 endif
 
 ifdef PYTHON
-tests += test-tgmath3
-generated += test-tgmath3.c
-CFLAGS-test-tgmath3.c += -fno-builtin
-
-$(objpfx)test-tgmath3.c: gen-tgmath-tests.py
-	$(PYTHON) $< > $@
+tgmath3-macros = atan2 cbrt ceil copysign erf erfc exp2 expm1 fdim floor \
+		 fma fmax fmin fmod frexp hypot ilogb ldexp lgamma llrint \
+		 llround log10 log1p log2 logb lrint lround nearbyint \
+		 nextafter nexttoward remainder remquo rint round scalbn \
+		 scalbln tgamma trunc acos asin atan acosh asinh atanh cos \
+		 sin tan cosh sinh tanh exp log pow sqrt fabs carg cimag conj \
+		 cproj creal roundeven nextup nextdown fminmag fmaxmag llogb \
+		 fromfp fromfpx ufromfp ufromfpx totalorder totalordermag \
+		 scalb
+tgmath3-macro-tests = $(addprefix test-tgmath3-,$(tgmath3-macros))
+tests += $(tgmath3-macro-tests)
+generated += $(addsuffix .c,$(tgmath3-macro-tests))
+
+$(tgmath3-macro-tests:%=$(objpfx)%.o): CFLAGS += -fno-builtin
+
+$(foreach m,$(tgmath3-macros),\
+	    $(objpfx)test-tgmath3-$(m).c): $(objpfx)test-tgmath3-%.c: \
+					   gen-tgmath-tests.py
+	$(PYTHON) gen-tgmath-tests.py $* > $@
+
+# Verify that the list of supported macros is in sync between the
+# Makefile and gen-tgmath-tests.py.
+tests-special += $(objpfx)test-tgmath3-macro-list.out
+$(objpfx)test-tgmath3-macro-list.out: gen-tgmath-tests.py
+	$(PYTHON) $< check-list $(tgmath3-macros) > $@; \
+	$(evaluate-test)
 endif
 
 libm-test-fast-math-cflags = -fno-builtin -D__FAST_MATH__ -DTEST_FAST_MATH
diff --git a/math/gen-tgmath-tests.py b/math/gen-tgmath-tests.py
index aad72f4b4b..9bbf703a31 100755
--- a/math/gen-tgmath-tests.py
+++ b/math/gen-tgmath-tests.py
@@ -55,6 +55,7 @@
 # uniquely determines the format.
 
 import string
+import sys
 
 class Type(object):
     """A type that may be used as an argument for generic parameters."""
@@ -351,6 +352,7 @@ class Tests(object):
             self.add_type_var(t.name, t.condition)
         self.test_text_list = []
         self.test_array_list = []
+        self.macros_seen = set()
 
     def add_type_var(self, name, cond):
         """Add declarations of variables for a type."""
@@ -361,13 +363,18 @@ class Tests(object):
         self.types_seen.add(name)
 
     def add_tests(self, macro, ret, args, complex_func=None):
-        """Add tests for a given tgmath.h macro."""
+        """Add tests for a given tgmath.h macro, if that is the macro for
+        which tests are to be generated; otherwise just add it to the
+        list of macros for which test generation is supported."""
         # 'c' means the function argument or return type is
         # type-generic and complex only (a complex function argument
         # may still have a real macro argument).  'g' means it is
         # type-generic and may be real or complex; 'r' means it is
         # type-generic and may only be real; 's' means the same as
         # 'r', but restricted to float, double and long double.
+        self.macros_seen.add(macro)
+        if macro != self.macro:
+            return
         have_complex = False
         func = macro
         if ret == 'c' or 'c' in args:
@@ -488,8 +495,10 @@ class Tests(object):
             test_func_text = if_cond_text(all_conds, test_func_text)
             self.test_text_list.append(test_func_text)
 
-    def add_all_tests(self):
-        """Add tests for all tgmath.h macros."""
+    def add_all_tests(self, macro):
+        """Add tests for the given tgmath.h macro, if any, and generate the
+        list of all supported macros."""
+        self.macro = macro
         # C99/C11 real-only functions.
         self.add_tests('atan2', 'r', ['r', 'r'])
         self.add_tests('cbrt', 'r', ['r'])
@@ -614,12 +623,27 @@ class Tests(object):
                        '#include <support/test-driver.c>']
         return ''.join(self.header_list + test_list + footer_list)
 
+    def check_macro_list(self, macro_list):
+        """Check the list of macros that can be tested."""
+        if self.macros_seen != set(macro_list):
+            print('error: macro list mismatch')
+            sys.exit(1)
+
 def main():
     """The main entry point."""
     Type.init_types()
     t = Tests()
-    t.add_all_tests()
-    print(t.tests_text())
+    if sys.argv[1] == 'check-list':
+        macro = None
+        macro_list = sys.argv[2:]
+    else:
+        macro = sys.argv[1]
+        macro_list = []
+    t.add_all_tests(macro)
+    if macro:
+        print(t.tests_text())
+    else:
+        t.check_macro_list(macro_list)
 
 if __name__ == '__main__':
     main()