[05/12] Refactor math/bits/math-finite.h, reusing math/bits/mathcalls.h [BZ #23292]

Message ID 20180620020426.20372-6-tuliom@linux.ibm.com
State Superseded
Delegated to: Joseph Myers
Headers

Commit Message

Tulio Magno Quites Machado Filho June 20, 2018, 2:04 a.m. UTC
  On a new enough compiler, redirecting the same function twice can cause
-Werror=pragmas errors.  This issue may appear when redirecting a
floating point function to a different ABI at the same time that finite
redirections are expected.

This patch removes all of the common redirections done in math-finite.h
in order to reuse mathcalls.h.  Prototypes and redirections are now
defined only once.  The finite functions are identified with macros
__MATHCALL_FINITE or __MATHCALL_VEC_FINITE.
When finite functions are not requested, the macros behave in the same
way as their non-finite peers, i.e. __MATHCALL and __MATHCALL_VEC.
However, when finite functions are requested, i.e.
__FINITE_MATH_ONLY__ > 0, they both redirect their functions via
__MATHREDIR, using __MATH_FINITE_NAME to set the name of the target
function.

In another change, math-finite.h inline functions are modified in order
to benefit from functions that have already been redirected.
Macro __REDIRTO_PUBLIC_F is used to reuse functions that are already
available in the API, e.g. lgammal is is an inline function that calls
__lgammal_r_finite, which has already been redirected via assembly to
__lgammaf128_r_finite.  The inline function could be directly redirected
to its respective f128 as it isn't guaranteed to be available in the API.

2018-06-19  Tulio Magno Quites Machado Filho  <tuliom@linux.ibm.com>

	[BZ #23292]
	* math/bits/math-finite.h: Move most of the functions to
	bits/mathcalls.h.
	* math/bits/mathcalls.h: Use macros __MATHCALL_FINITE and
	__MATHCALL_VEC_FINITE to identify finite functions.
	* math/math.h (__MATH_FINITE_NAMEY, __MATH_FINITE_NAMEX,
	__MATH_FINITE_NAME_IMPL, __MATH_FINITE_NAME,
	__MATHCALL_VEC_FINITE, __MATHCALL_FINITE):
	New macros.
	[defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0]: Include
	bits/math-finite.h for double, float and long double earlier in
	order to use its functions from the math-finite.h of _FloatN types.

Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
---
 math/bits/math-finite.h | 160 ++++-------------
 math/bits/mathcalls.h   |  53 +++---
 math/math.h             | 466 +++++++++++++++++++++++++-----------------------
 3 files changed, 296 insertions(+), 383 deletions(-)
  

Comments

Joseph Myers June 20, 2018, 10:41 a.m. UTC | #1
I don't see anything in this patch to ensure that the redirections now 
done through bits/mathcalls.h don't apply on ia64, as that doesn't have 
__*_finite (e.g. a new bits/ header defining a macro for whether _finite 
redirects are supported, for which ia64 provides its own version).
  

Patch

diff --git a/math/bits/math-finite.h b/math/bits/math-finite.h
index 0799fe7b29..7a23b234cc 100644
--- a/math/bits/math-finite.h
+++ b/math/bits/math-finite.h
@@ -20,96 +20,27 @@ 
 # error "Never use <bits/math-finite.h> directly; include <math.h> instead."
 #endif
 
-#define __REDIRFROM(...) __REDIRFROM_X(__VA_ARGS__)
+#define __REDIRFROM_F(...) __REDIRFROM_X(__VA_ARGS__)
 
-#define __REDIRTO(...) __REDIRTO_X(__VA_ARGS__)
+#define __REDIRTO_F(...) __REDIRTO_X(__VA_ARGS__)
 
-#define __MATH_REDIRCALL_X(from, args, to) \
-  extern _Mdouble_ __REDIRECT_NTH (from, args, to)
-#define __MATH_REDIRCALL(function, reentrant, args) \
-  __MATH_REDIRCALL_X \
-   (__REDIRFROM (function, reentrant), args, \
-    __REDIRTO (function, reentrant))
-#define __MATH_REDIRCALL_2(from, reentrant, args, to) \
-  __MATH_REDIRCALL_X \
-   (__REDIRFROM (from, reentrant), args, \
-    __REDIRTO (to, reentrant))
-
-#define __MATH_REDIRCALL_INTERNAL(function, reentrant, args) \
-  __MATH_REDIRCALL_X \
-   (__REDIRFROM (__CONCAT (__, function), \
-		 __CONCAT (reentrant, _finite)), \
-    args, __REDIRTO (function, _r))
-
-
-/* acos.  */
-__MATH_REDIRCALL (acos, , (_Mdouble_));
-
-#if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
-/* acosh.  */
-__MATH_REDIRCALL (acosh, , (_Mdouble_));
-#endif
-
-/* asin.  */
-__MATH_REDIRCALL (asin, , (_Mdouble_));
-
-/* atan2.  */
-__MATH_REDIRCALL (atan2, , (_Mdouble_, _Mdouble_));
-
-#if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
-/* atanh.  */
-__MATH_REDIRCALL (atanh, , (_Mdouble_));
-#endif
-
-/* cosh.  */
-__MATH_REDIRCALL (cosh, , (_Mdouble_));
-
-/* exp.  */
-__MATH_REDIRCALL (exp, , (_Mdouble_));
-
-#if __GLIBC_USE (IEC_60559_FUNCS_EXT)
-/* exp10.  */
-__MATH_REDIRCALL (exp10, , (_Mdouble_));
-#endif
-
-#ifdef __USE_ISOC99
-/* exp2.  */
-__MATH_REDIRCALL (exp2, , (_Mdouble_));
-#endif
-
-/* fmod.  */
-__MATH_REDIRCALL (fmod, , (_Mdouble_, _Mdouble_));
-
-#if defined __USE_XOPEN || defined __USE_ISOC99
-/* hypot.  */
-__MATH_REDIRCALL (hypot, , (_Mdouble_, _Mdouble_));
-#endif
+/* Redirects to a function that is part of the API.  */
+#define __REDIRTO_PUBLIC_F(...) __REDIRTO_PUBLIC_X(__VA_ARGS__)
 
-#if (__MATH_DECLARING_DOUBLE && (defined __USE_MISC || defined __USE_XOPEN)) \
-    || (!__MATH_DECLARING_DOUBLE && defined __USE_MISC)
-/* j0.  */
-__MATH_REDIRCALL (j0, , (_Mdouble_));
+#define __MATH_REDIR_X(type, from, args, to) \
+  extern type __REDIRECT_NTH (from, args, to)
 
-/* y0.  */
-__MATH_REDIRCALL (y0, , (_Mdouble_));
-
-/* j1.  */
-__MATH_REDIRCALL (j1, , (_Mdouble_));
-
-/* y1.  */
-__MATH_REDIRCALL (y1, , (_Mdouble_));
-
-/* jn.  */
-__MATH_REDIRCALL (jn, , (int, _Mdouble_));
+#define __MATH_REDIRCALL(function, reentrant, args) \
+  __MATH_REDIR_X (_Mdouble_, \
+		  __REDIRFROM_F (function, reentrant), args, \
+		  __REDIRTO_F (function, reentrant))
 
-/* yn.  */
-__MATH_REDIRCALL (yn, , (int, _Mdouble_));
-#endif
+#define __MATH_REDIRCALL_INTERNAL(function, reentrant, args) \
+  __MATH_REDIR_X (_Mdouble_, \
+		  __REDIRFROM_F (__CONCAT (__, function), \
+				 __CONCAT (reentrant, _finite)), \
+		  args, __REDIRTO_F (function, _r))
 
-#ifdef __USE_MISC
-/* lgamma_r.  */
-__MATH_REDIRCALL (lgamma, _r, (_Mdouble_, int *));
-#endif
 
 /* Redirect __lgammal_r_finite to __lgamma_r_finite when __NO_LONG_DOUBLE_MATH
    is set and to itself otherwise.  It also redirects __lgamma_r_finite and
@@ -120,13 +51,13 @@  __MATH_REDIRCALL_INTERNAL (lgamma, _r, (_Mdouble_, int *));
      && defined __extern_always_inline)
 /* lgamma.  */
 __extern_always_inline _Mdouble_
-__NTH (__REDIRFROM (lgamma, ) (_Mdouble_ __d))
+__NTH (__REDIRFROM_F (lgamma, ) (_Mdouble_ __d))
 {
 # if defined __USE_MISC || defined __USE_XOPEN
-  return __REDIRTO (lgamma, _r) (__d, &signgam);
+  return __REDIRTO_PUBLIC_F (lgamma, _r) (__d, &signgam);
 # else
   int __local_signgam = 0;
-  return __REDIRTO (lgamma, _r) (__d, &__local_signgam);
+  return __REDIRTO_PUBLIC_F (lgamma, _r) (__d, &__local_signgam);
 # endif
 }
 #endif
@@ -135,63 +66,32 @@  __NTH (__REDIRFROM (lgamma, ) (_Mdouble_ __d))
      && defined __extern_always_inline) && !__MATH_DECLARING_FLOATN
 /* gamma.  */
 __extern_always_inline _Mdouble_
-__NTH (__REDIRFROM (gamma, ) (_Mdouble_ __d))
+__NTH (__REDIRFROM_F (gamma, ) (_Mdouble_ __d))
 {
-  return __REDIRTO (lgamma, _r) (__d, &signgam);
+  return __REDIRTO_PUBLIC_F (lgamma, _r) (__d, &signgam);
 }
 #endif
 
-/* log.  */
-__MATH_REDIRCALL (log, , (_Mdouble_));
-
-/* log10.  */
-__MATH_REDIRCALL (log10, , (_Mdouble_));
-
-#ifdef __USE_ISOC99
-/* log2.  */
-__MATH_REDIRCALL (log2, , (_Mdouble_));
-#endif
-
-/* pow.  */
-__MATH_REDIRCALL (pow, , (_Mdouble_, _Mdouble_));
-
-#if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
-/* remainder.  */
-__MATH_REDIRCALL (remainder, , (_Mdouble_, _Mdouble_));
-#endif
-
-#if ((__MATH_DECLARING_DOUBLE \
-      && (defined __USE_MISC \
-	  || (defined __USE_XOPEN_EXTENDED && !defined __USE_XOPEN2K8))) \
-     || (!defined __MATH_DECLARE_LDOUBLE && defined __USE_MISC)) \
-    && !__MATH_DECLARING_FLOATN
-/* scalb.  */
-__MATH_REDIRCALL (scalb, , (_Mdouble_, _Mdouble_));
-#endif
-
-/* sinh.  */
-__MATH_REDIRCALL (sinh, , (_Mdouble_));
-
-/* sqrt.  */
-__MATH_REDIRCALL (sqrt, , (_Mdouble_));
-
 #if defined __USE_ISOC99 && defined __extern_always_inline
 /* tgamma.  */
+# if __HAVE_DISTINCT_FLOAT128 && !__HAVE_FLOAT128_UNLIKE_LDBL
+__MATH_REDIRCALL_INTERNAL (gamma, _r, (_Mdouble_, int *));
+# else
 extern _Mdouble_
-__REDIRFROM (__gamma, _r_finite) (_Mdouble_, int *);
+__REDIRFROM_F (__gamma, _r_finite) (_Mdouble_, int *);
+# endif
 
 __extern_always_inline _Mdouble_
-__NTH (__REDIRFROM (tgamma, ) (_Mdouble_ __d))
+__NTH (__REDIRFROM_F (tgamma, ) (_Mdouble_ __d))
 {
   int __local_signgam = 0;
-  _Mdouble_ __res = __REDIRTO (gamma, _r) (__d, &__local_signgam);
+  _Mdouble_ __res = __REDIRTO_PUBLIC_F (gamma, _r) (__d, &__local_signgam);
   return __local_signgam < 0 ? -__res : __res;
 }
 #endif
 
-#undef __REDIRFROM
-#undef __REDIRTO
 #undef __MATH_REDIRCALL
-#undef __MATH_REDIRCALL_2
 #undef __MATH_REDIRCALL_INTERNAL
-#undef __MATH_REDIRCALL_X
+#undef __MATH_REDIR_X
+#undef __REDIRFROM_F
+#undef __REDIRTO_F
diff --git a/math/bits/mathcalls.h b/math/bits/mathcalls.h
index cf87313e2f..f4246a7881 100644
--- a/math/bits/mathcalls.h
+++ b/math/bits/mathcalls.h
@@ -50,13 +50,13 @@ 
 /* Trigonometric functions.  */
 
 /* Arc cosine of X.  */
-__MATHCALL (acos,, (_Mdouble_ __x));
+__MATHCALL_FINITE (acos,, (_Mdouble_ __x));
 /* Arc sine of X.  */
-__MATHCALL (asin,, (_Mdouble_ __x));
+__MATHCALL_FINITE (asin,, (_Mdouble_ __x));
 /* Arc tangent of X.  */
 __MATHCALL (atan,, (_Mdouble_ __x));
 /* Arc tangent of Y/X.  */
-__MATHCALL (atan2,, (_Mdouble_ __y, _Mdouble_ __x));
+__MATHCALL_FINITE (atan2,, (_Mdouble_ __y, _Mdouble_ __x));
 
 /* Cosine of X.  */
 __MATHCALL_VEC (cos,, (_Mdouble_ __x));
@@ -68,9 +68,9 @@  __MATHCALL (tan,, (_Mdouble_ __x));
 /* Hyperbolic functions.  */
 
 /* Hyperbolic cosine of X.  */
-__MATHCALL (cosh,, (_Mdouble_ __x));
+__MATHCALL_FINITE (cosh,, (_Mdouble_ __x));
 /* Hyperbolic sine of X.  */
-__MATHCALL (sinh,, (_Mdouble_ __x));
+__MATHCALL_FINITE (sinh,, (_Mdouble_ __x));
 /* Hyperbolic tangent of X.  */
 __MATHCALL (tanh,, (_Mdouble_ __x));
 
@@ -82,17 +82,17 @@  __MATHDECL_VEC (void,sincos,,
 
 #if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
 /* Hyperbolic arc cosine of X.  */
-__MATHCALL (acosh,, (_Mdouble_ __x));
+__MATHCALL_FINITE (acosh,, (_Mdouble_ __x));
 /* Hyperbolic arc sine of X.  */
 __MATHCALL (asinh,, (_Mdouble_ __x));
 /* Hyperbolic arc tangent of X.  */
-__MATHCALL (atanh,, (_Mdouble_ __x));
+__MATHCALL_FINITE (atanh,, (_Mdouble_ __x));
 #endif
 
 /* Exponential and logarithmic functions.  */
 
 /* Exponential function of X.  */
-__MATHCALL_VEC (exp,, (_Mdouble_ __x));
+__MATHCALL_VEC_FINITE (exp,, (_Mdouble_ __x));
 
 /* Break VALUE into a normalized fraction and an integral power of 2.  */
 __MATHCALL (frexp,, (_Mdouble_ __x, int *__exponent));
@@ -101,17 +101,17 @@  __MATHCALL (frexp,, (_Mdouble_ __x, int *__exponent));
 __MATHCALL (ldexp,, (_Mdouble_ __x, int __exponent));
 
 /* Natural logarithm of X.  */
-__MATHCALL_VEC (log,, (_Mdouble_ __x));
+__MATHCALL_VEC_FINITE (log,, (_Mdouble_ __x));
 
 /* Base-ten logarithm of X.  */
-__MATHCALL (log10,, (_Mdouble_ __x));
+__MATHCALL_FINITE (log10,, (_Mdouble_ __x));
 
 /* Break VALUE into integral and fractional parts.  */
 __MATHCALL (modf,, (_Mdouble_ __x, _Mdouble_ *__iptr)) __nonnull ((2));
 
 #if __GLIBC_USE (IEC_60559_FUNCS_EXT)
 /* Compute exponent to base ten.  */
-__MATHCALL (exp10,, (_Mdouble_ __x));
+__MATHCALL_FINITE (exp10,, (_Mdouble_ __x));
 #endif
 
 #if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
@@ -127,24 +127,23 @@  __MATHCALL (logb,, (_Mdouble_ __x));
 
 #ifdef __USE_ISOC99
 /* Compute base-2 exponential of X.  */
-__MATHCALL (exp2,, (_Mdouble_ __x));
+__MATHCALL_FINITE (exp2,, (_Mdouble_ __x));
 
 /* Compute base-2 logarithm of X.  */
-__MATHCALL (log2,, (_Mdouble_ __x));
+__MATHCALL_FINITE (log2,, (_Mdouble_ __x));
 #endif
 
-
 /* Power functions.  */
 
 /* Return X to the Y power.  */
-__MATHCALL_VEC (pow,, (_Mdouble_ __x, _Mdouble_ __y));
+__MATHCALL_VEC_FINITE (pow,, (_Mdouble_ __x, _Mdouble_ __y));
 
 /* Return the square root of X.  */
-__MATHCALL (sqrt,, (_Mdouble_ __x));
+__MATHCALL_FINITE (sqrt,, (_Mdouble_ __x));
 
 #if defined __USE_XOPEN || defined __USE_ISOC99
 /* Return `sqrt(X*X + Y*Y)'.  */
-__MATHCALL (hypot,, (_Mdouble_ __x, _Mdouble_ __y));
+__MATHCALL_FINITE (hypot,, (_Mdouble_ __x, _Mdouble_ __y));
 #endif
 
 #if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
@@ -165,7 +164,7 @@  __MATHCALLX (fabs,, (_Mdouble_ __x), (__const__));
 __MATHCALLX (floor,, (_Mdouble_ __x), (__const__));
 
 /* Floating-point modulo remainder of X/Y.  */
-__MATHCALL (fmod,, (_Mdouble_ __x, _Mdouble_ __y));
+__MATHCALL_FINITE (fmod,, (_Mdouble_ __x, _Mdouble_ __y));
 
 #ifdef __USE_MISC
 # if ((!defined __cplusplus \
@@ -214,12 +213,12 @@  __MATHDECL_1 (int,isnan,, (_Mdouble_ __value)) __attribute__ ((__const__));
 
 #if defined __USE_MISC || (defined __USE_XOPEN && __MATH_DECLARING_DOUBLE)
 /* Bessel functions.  */
-__MATHCALL (j0,, (_Mdouble_));
-__MATHCALL (j1,, (_Mdouble_));
-__MATHCALL (jn,, (int, _Mdouble_));
-__MATHCALL (y0,, (_Mdouble_));
-__MATHCALL (y1,, (_Mdouble_));
-__MATHCALL (yn,, (int, _Mdouble_));
+__MATHCALL_FINITE (j0,, (_Mdouble_));
+__MATHCALL_FINITE (j1,, (_Mdouble_));
+__MATHCALL_FINITE (jn,, (int, _Mdouble_));
+__MATHCALL_FINITE (y0,, (_Mdouble_));
+__MATHCALL_FINITE (y1,, (_Mdouble_));
+__MATHCALL_FINITE (yn,, (int, _Mdouble_));
 #endif
 
 
@@ -246,7 +245,7 @@  __MATHCALL (gamma,, (_Mdouble_));
 /* Reentrant version of lgamma.  This function uses the global variable
    `signgam'.  The reentrant version instead takes a pointer and stores
    the value through it.  */
-__MATHCALL (lgamma,_r, (_Mdouble_, int *__signgamp));
+__MATHCALL_FINITE (lgamma,_r, (_Mdouble_, int *__signgamp));
 #endif
 
 
@@ -269,7 +268,7 @@  __MATHCALL (nextup,, (_Mdouble_ __x));
 # endif
 
 /* Return the remainder of integer divison X / Y with infinite precision.  */
-__MATHCALL (remainder,, (_Mdouble_ __x, _Mdouble_ __y));
+__MATHCALL_FINITE (remainder,, (_Mdouble_ __x, _Mdouble_ __y));
 
 # ifdef __USE_ISOC99
 /* Return X times (2 to the Nth power).  */
@@ -393,5 +392,5 @@  __MATHDECL_1 (int, setpayloadsig,, (_Mdouble_ *__x, _Mdouble_ __payload));
 			    && !defined __USE_XOPEN2K8))  \
      && !__MATH_DECLARING_FLOATN
 /* Return X times (2 to the Nth power).  */
-__MATHCALL (scalb,, (_Mdouble_ __x, _Mdouble_ __n));
+__MATHCALL_FINITE (scalb,, (_Mdouble_ __x, _Mdouble_ __n));
 #endif
diff --git a/math/math.h b/math/math.h
index 998d3042c5..c1765e4c8c 100644
--- a/math/math.h
+++ b/math/math.h
@@ -286,6 +286,28 @@  enum
 
 #define __MATHREDIR(type, function, suffix, args, to) \
   extern type __REDIRECT_NTH (__MATH_PRECNAME (function, suffix), args, to)
+#define __MATH_FINITE_NAMEY(p, f, s) \
+  p ## f ## s
+#define __MATH_FINITE_NAMEX(p, f, s) \
+  __MATH_FINITE_NAMEY (p, f, s)
+#define __MATH_FINITE_NAME_IMPL(function, suffix) \
+  __MATH_FINITE_NAMEX (__, __MATH_PRECNAME (function, suffix), _finite)
+#define __MATH_FINITE_NAME(function, suffix) \
+  __MATH_FINITE_NAME_IMPL (function, suffix)
+
+#if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+# define __MATHCALL_VEC_FINITE(function, suffix, args) \
+  __SIMD_DECL (__MATH_PRECNAME (function, suffix)) \
+  __MATHCALL_FINITE (function, suffix, args)
+# define __MATHCALL_FINITE(function, suffix, args) \
+  __MATHREDIR (_Mdouble_, function, suffix, args, \
+	       __MATH_FINITE_NAME(function, suffix))
+#else
+# define __MATHCALL_VEC_FINITE(function, suffix, args) \
+  __MATHCALL_VEC(function, suffix, args)
+# define __MATHCALL_FINITE(function, suffix, args) \
+  __MATHCALL (function, suffix, args)
+#endif
 
 #define _Mdouble_		double
 #define __MATH_PRECNAME(name,r)	__CONCAT(name,r)
@@ -320,6 +342,10 @@  enum
      || defined _LIBC_TEST
 #  ifdef __LDBL_COMPAT
 
+#   undef __MATH_FINITE_NAME
+#   define __MATH_FINITE_NAME(function, suffix) \
+  __MATH_FINITE_NAMEX (__, function ## suffix, _finite)
+
 #   ifdef __USE_ISOC99
 extern float __nldbl_nexttowardf (float __x, long double __y)
 				  __THROW __attribute__ ((__const__));
@@ -364,8 +390,99 @@  extern long double __REDIRECT_NTH (nexttowardl,
 
 #endif	/* Use ISO C99.  */
 
+#if defined __USE_MISC || defined __USE_XOPEN
+/* This variable is used by `gamma' and `lgamma'.  */
+extern int signgam;
+#endif
+
+/* Define special entry points to use when the compiler got told to
+   only expect finite results.  */
+#if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+
+/* Include bits/math-finite.h for double.  */
+# define _Mdouble_ double
+# define __MATH_DECLARING_DOUBLE 1
+# define __MATH_DECLARING_FLOATN 0
+# define __REDIRFROM_X(function, reentrant) \
+  function ## reentrant
+# define __REDIRTO_X(function, reentrant) \
+   __ ## function ## reentrant ## _finite
+# define __REDIRTO_PUBLIC_X(function, reentrant) \
+  __REDIRTO_X(function, reentrant)
+# include <bits/math-finite.h>
+# undef _Mdouble_
+# undef __MATH_DECLARING_DOUBLE
+# undef __MATH_DECLARING_FLOATN
+# undef __REDIRFROM_X
+# undef __REDIRTO_X
+# undef __REDIRTO_PUBLIC_X
+
+/* When __USE_ISOC99 is defined, include math-finite for float and
+   long double, as well.  */
+# ifdef __USE_ISOC99
+
+/* Include bits/math-finite.h for float.  */
+#  define _Mdouble_ float
+#  define __MATH_DECLARING_DOUBLE 0
+#  define __MATH_DECLARING_FLOATN 0
+#  define __REDIRFROM_X(function, reentrant) \
+  function ## f ## reentrant
+#  define __REDIRTO_X(function, reentrant) \
+   __ ## function ## f ## reentrant ## _finite
+# define __REDIRTO_PUBLIC_X(function, reentrant) \
+  __REDIRTO_X(function, reentrant)
+#  include <bits/math-finite.h>
+#  undef _Mdouble_
+#  undef __MATH_DECLARING_DOUBLE
+#  undef __MATH_DECLARING_FLOATN
+#  undef __REDIRFROM_X
+#  undef __REDIRTO_X
+#  undef __REDIRTO_PUBLIC_X
+
+/* Include bits/math-finite.h for long double.  */
+#  ifdef __MATH_DECLARE_LDOUBLE
+#   define _Mdouble_ long double
+#   define __MATH_DECLARING_DOUBLE 0
+#   define __MATH_DECLARING_FLOATN 0
+#   define __REDIRFROM_X(function, reentrant) \
+  function ## l ## reentrant
+#   ifdef __NO_LONG_DOUBLE_MATH
+#    define __REDIRTO_X(function, reentrant) \
+   __ ## function ## reentrant ## _finite
+#    define __REDIRTO_PUBLIC_X(function, reentrant) \
+   __REDIRTO_X(function, reentrant)
+#   elif __HAVE_DISTINCT_FLOAT128 && !__HAVE_FLOAT128_UNLIKE_LDBL
+#    define __REDIRTO_X(function, reentrant)	\
+   __ ## function ## f128 ## reentrant ## _finite
+#    define __REDIRTO_PUBLIC_X(function, reentrant) \
+   __ ## function ## l ## reentrant ## _finite
+#   else
+#    define __REDIRTO_X(function, reentrant) \
+   __ ## function ## l ## reentrant ## _finite
+#    define __REDIRTO_PUBLIC_X(function, reentrant) \
+   __REDIRTO_X(function, reentrant)
+#   endif
+#   include <bits/math-finite.h>
+#   undef _Mdouble_
+#   undef __MATH_DECLARING_DOUBLE
+#   undef __MATH_DECLARING_FLOATN
+#   undef __REDIRFROM_X
+#   undef __REDIRTO_X
+#   undef __REDIRTO_PUBLIC_X
+#  endif
+
+# endif /* __USE_ISOC99.  */
+#endif /* __FINITE_MATH_ONLY__ > 0.  */
+
 /* Include the file of declarations for _FloatN and _FloatNx
    types.  */
+#undef __MATH_FINITE_NAME
+#define __MATH_FINITE_NAME(function, suffix) \
+  __MATH_FINITE_NAMEX (, __REDIRTO_X (function, suffix),)
+#define __REDIRFROM_X(function, reentrant) \
+  __MATH_PRECNAME (function, reentrant)
+#define __REDIRTO_PUBLIC_X(function, reentrant) \
+  __REDIRTO_X(function, reentrant)
 
 #if __HAVE_DISTINCT_FLOAT16 || (__HAVE_FLOAT16 && !defined _LIBC)
 # define _Mdouble_		_Float16
@@ -376,12 +493,27 @@  extern long double __REDIRECT_NTH (nexttowardl,
 #  include <bits/mathcalls-helper-functions.h>
 # endif
 # if __GLIBC_USE (IEC_60559_TYPES_EXT)
+#  if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+#   if __HAVE_DISTINCT_FLOAT16
+#    define __REDIRTO_X(function, reentrant) \
+  __ ## function ## f16 ## reentrant ## _finite
+#   else
+#    error "non-distinct _Float16"
+#   endif
+#  else
+#   define __REDIRTO_X(function, reentrant) \
+  __MATH_PRECNAME (function, reentrant)
+#  endif
 #  include <bits/mathcalls.h>
+#  if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+#   include <bits/math-finite.h>
+#  endif
 # endif
 # undef _Mdouble_
 # undef __MATH_PRECNAME
 # undef __MATH_DECLARING_DOUBLE
 # undef __MATH_DECLARING_FLOATN
+# undef __REDIRTO_X
 #endif /* __HAVE_DISTINCT_FLOAT16 || (__HAVE_FLOAT16 && !_LIBC).  */
 
 #if __HAVE_DISTINCT_FLOAT32 || (__HAVE_FLOAT32 && !defined _LIBC)
@@ -393,12 +525,28 @@  extern long double __REDIRECT_NTH (nexttowardl,
 #  include <bits/mathcalls-helper-functions.h>
 # endif
 # if __GLIBC_USE (IEC_60559_TYPES_EXT)
+#  if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+#   if __HAVE_DISTINCT_FLOAT32
+#    define __REDIRTO_X(function, reentrant) \
+  __ ## function ## f32 ## reentrant ## _finite
+#   else
+#    define __REDIRTO_X(function, reentrant) \
+  __ ## function ## f ## reentrant ## _finite
+#   endif
+#  else
+#   define __REDIRTO_X(function, reentrant) \
+  __MATH_PRECNAME (function, reentrant)
+#  endif
 #  include <bits/mathcalls.h>
+#  if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+#   include <bits/math-finite.h>
+#  endif
 # endif
 # undef _Mdouble_
 # undef __MATH_PRECNAME
 # undef __MATH_DECLARING_DOUBLE
 # undef __MATH_DECLARING_FLOATN
+# undef __REDIRTO_X
 #endif /* __HAVE_DISTINCT_FLOAT32 || (__HAVE_FLOAT32 && !_LIBC).  */
 
 #if __HAVE_DISTINCT_FLOAT64 || (__HAVE_FLOAT64 && !defined _LIBC)
@@ -410,12 +558,28 @@  extern long double __REDIRECT_NTH (nexttowardl,
 #  include <bits/mathcalls-helper-functions.h>
 # endif
 # if __GLIBC_USE (IEC_60559_TYPES_EXT)
+#  if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+#   if __HAVE_DISTINCT_FLOAT64
+#    define __REDIRTO_X(function, reentrant) \
+  __ ## function ## f64 ## reentrant ## _finite
+#   else
+#    define __REDIRTO_X(function, reentrant) \
+  __ ## function ## reentrant ## _finite
+#   endif
+#  else
+#   define __REDIRTO_X(function, reentrant) \
+  __MATH_PRECNAME (function, reentrant)
+#  endif
 #  include <bits/mathcalls.h>
+#  if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+#   include <bits/math-finite.h>
+#  endif
 # endif
 # undef _Mdouble_
 # undef __MATH_PRECNAME
 # undef __MATH_DECLARING_DOUBLE
 # undef __MATH_DECLARING_FLOATN
+# undef __REDIRTO_X
 #endif /* __HAVE_DISTINCT_FLOAT64 || (__HAVE_FLOAT64 && !_LIBC).  */
 
 #if __HAVE_DISTINCT_FLOAT128 || (__HAVE_FLOAT128 && !defined _LIBC)
@@ -427,12 +591,28 @@  extern long double __REDIRECT_NTH (nexttowardl,
 #  include <bits/mathcalls-helper-functions.h>
 # endif
 # if __GLIBC_USE (IEC_60559_TYPES_EXT)
+#  if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+#   if __HAVE_DISTINCT_FLOAT128
+#    define __REDIRTO_X(function, reentrant) \
+  __ ## function ## f128 ## reentrant ## _finite
+#   else
+#    define __REDIRTO_X(function, reentrant) \
+  __ ## function ## l ## reentrant ## _finite
+#   endif
+#  else
+#   define __REDIRTO_X(function, reentrant) \
+  __MATH_PRECNAME (function, reentrant)
+#  endif
 #  include <bits/mathcalls.h>
+#  if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+#   include <bits/math-finite.h>
+#  endif
 # endif
 # undef _Mdouble_
 # undef __MATH_PRECNAME
 # undef __MATH_DECLARING_DOUBLE
 # undef __MATH_DECLARING_FLOATN
+# undef __REDIRTO_X
 #endif /* __HAVE_DISTINCT_FLOAT128 || (__HAVE_FLOAT128 && !_LIBC).  */
 
 #if __HAVE_DISTINCT_FLOAT32X || (__HAVE_FLOAT32X && !defined _LIBC)
@@ -444,12 +624,28 @@  extern long double __REDIRECT_NTH (nexttowardl,
 #  include <bits/mathcalls-helper-functions.h>
 # endif
 # if __GLIBC_USE (IEC_60559_TYPES_EXT)
+#  if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+#   if __HAVE_DISTINCT_FLOAT32X
+#    define __REDIRTO_X(function, reentrant) \
+  __ ## function ## f32x ## reentrant ## _finite
+#   else
+#    define __REDIRTO_X(function, reentrant) \
+  __ ## function ## reentrant ## _finite
+#   endif
+#  else
+#   define __REDIRTO_X(function, reentrant) \
+  __MATH_PRECNAME (function, reentrant)
+#  endif
 #  include <bits/mathcalls.h>
+#  if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+#   include <bits/math-finite.h>
+#  endif
 # endif
 # undef _Mdouble_
 # undef __MATH_PRECNAME
 # undef __MATH_DECLARING_DOUBLE
 # undef __MATH_DECLARING_FLOATN
+# undef __REDIRTO_X
 #endif /* __HAVE_DISTINCT_FLOAT32X || (__HAVE_FLOAT32X && !_LIBC).  */
 
 #if __HAVE_DISTINCT_FLOAT64X || (__HAVE_FLOAT64X && !defined _LIBC)
@@ -461,12 +657,31 @@  extern long double __REDIRECT_NTH (nexttowardl,
 #  include <bits/mathcalls-helper-functions.h>
 # endif
 # if __GLIBC_USE (IEC_60559_TYPES_EXT)
+#  if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+#   if __HAVE_DISTINCT_FLOAT64X
+#    define __REDIRTO_X(function, reentrant) \
+  __ ## function ## f64x ## reentrant ## _finite
+#   elif __HAVE_FLOAT64X_LONG_DOUBLE
+#    define __REDIRTO_X(function, reentrant) \
+  __ ## function ## l ## reentrant ## _finite
+#   else
+#    define __REDIRTO_X(function, reentrant) \
+  __ ## function ## f128 ## reentrant ## _finite
+#   endif
+#  else
+#   define __REDIRTO_X(function, reentrant) \
+  __MATH_PRECNAME (function, reentrant)
+#  endif
 #  include <bits/mathcalls.h>
+#  if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+#   include <bits/math-finite.h>
+#  endif
 # endif
 # undef _Mdouble_
 # undef __MATH_PRECNAME
 # undef __MATH_DECLARING_DOUBLE
 # undef __MATH_DECLARING_FLOATN
+# undef __REDIRTO_X
 #endif /* __HAVE_DISTINCT_FLOAT64X || (__HAVE_FLOAT64X && !_LIBC).  */
 
 #if __HAVE_DISTINCT_FLOAT128X || (__HAVE_FLOAT128X && !defined _LIBC)
@@ -478,18 +693,43 @@  extern long double __REDIRECT_NTH (nexttowardl,
 #  include <bits/mathcalls-helper-functions.h>
 # endif
 # if __GLIBC_USE (IEC_60559_TYPES_EXT)
+#  if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+#   if __HAVE_DISTINCT_FLOAT128X
+#    define __REDIRTO_X(function, reentrant) \
+  __ ## function ## f128x ## reentrant ## _finite
+#   else
+#    error "non-distinct _Float128x"
+#   endif
+#  else
+#   define __REDIRTO_X(function, reentrant) \
+  __MATH_PRECNAME (function, reentrant)
+#  endif
 #  include <bits/mathcalls.h>
+#  if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
+#   include <bits/math-finite.h>
+#  endif
 # endif
 # undef _Mdouble_
 # undef __MATH_PRECNAME
 # undef __MATH_DECLARING_DOUBLE
 # undef __MATH_DECLARING_FLOATN
+# undef __REDIRTO_X
 #endif /* __HAVE_DISTINCT_FLOAT128X || (__HAVE_FLOAT128X && !_LIBC).  */
 
+#undef	__REDIRFROM_X
+#undef	__REDIRTO_PUBLIC_X
 #undef	__MATHDECL_1_IMPL
 #undef	__MATHDECL_1
 #undef	__MATHDECL
 #undef	__MATHCALL
+#undef	__MATHCALL_VEC
+#undef	__MATHCALL_FINITE
+#undef	__MATHCALL_VEC_FINITE
+#undef	__MATHREDIR
+#undef	__MATH_FINITE_NAMEY
+#undef	__MATH_FINITE_NAMEX
+#undef	__MATH_FINITE_NAME_IMPL
+#undef	__MATH_FINITE_NAME
 
 /* Declare functions returning a narrower type.  */
 #define __MATHCALL_NARROW_ARGS_1 (_Marg_ __x)
@@ -776,11 +1016,6 @@  extern long double __REDIRECT_NTH (nexttowardl,
 #undef __MATHCALL_NARROW_REDIR
 #undef __MATHCALL_NARROW
 
-#if defined __USE_MISC || defined __USE_XOPEN
-/* This variable is used by `gamma' and `lgamma'.  */
-extern int signgam;
-#endif
-
 #if (__HAVE_DISTINCT_FLOAT16			\
      || __HAVE_DISTINCT_FLOAT32			\
      || __HAVE_DISTINCT_FLOAT64			\
@@ -1248,227 +1483,6 @@  iszero (__T __val)
 # include <bits/mathinline.h>
 #endif
 
-/* Define special entry points to use when the compiler got told to
-   only expect finite results.  */
-#if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0
-
-/* Include bits/math-finite.h for double.  */
-# define _Mdouble_ double
-# define __MATH_DECLARING_DOUBLE 1
-# define __MATH_DECLARING_FLOATN 0
-# define __REDIRFROM_X(function, reentrant) \
-  function ## reentrant
-# define __REDIRTO_X(function, reentrant) \
-   __ ## function ## reentrant ## _finite
-# include <bits/math-finite.h>
-# undef _Mdouble_
-# undef __MATH_DECLARING_DOUBLE
-# undef __MATH_DECLARING_FLOATN
-# undef __REDIRFROM_X
-# undef __REDIRTO_X
-
-/* When __USE_ISOC99 is defined, include math-finite for float and
-   long double, as well.  */
-# ifdef __USE_ISOC99
-
-/* Include bits/math-finite.h for float.  */
-#  define _Mdouble_ float
-#  define __MATH_DECLARING_DOUBLE 0
-#  define __MATH_DECLARING_FLOATN 0
-#  define __REDIRFROM_X(function, reentrant) \
-  function ## f ## reentrant
-#  define __REDIRTO_X(function, reentrant) \
-   __ ## function ## f ## reentrant ## _finite
-#  include <bits/math-finite.h>
-#  undef _Mdouble_
-#  undef __MATH_DECLARING_DOUBLE
-#  undef __MATH_DECLARING_FLOATN
-#  undef __REDIRFROM_X
-#  undef __REDIRTO_X
-
-/* Include bits/math-finite.h for long double.  */
-#  ifdef __MATH_DECLARE_LDOUBLE
-#   define _Mdouble_ long double
-#   define __MATH_DECLARING_DOUBLE 0
-#   define __MATH_DECLARING_FLOATN 0
-#   define __REDIRFROM_X(function, reentrant) \
-  function ## l ## reentrant
-#   ifdef __NO_LONG_DOUBLE_MATH
-#    define __REDIRTO_X(function, reentrant) \
-   __ ## function ## reentrant ## _finite
-#   else
-#    define __REDIRTO_X(function, reentrant) \
-   __ ## function ## l ## reentrant ## _finite
-#   endif
-#   include <bits/math-finite.h>
-#   undef _Mdouble_
-#   undef __MATH_DECLARING_DOUBLE
-#   undef __MATH_DECLARING_FLOATN
-#   undef __REDIRFROM_X
-#   undef __REDIRTO_X
-#  endif
-
-# endif /* __USE_ISOC99.  */
-
-/* Include bits/math-finite.h for _FloatN and _FloatNx.  */
-
-# if (__HAVE_DISTINCT_FLOAT16 || (__HAVE_FLOAT16 && !defined _LIBC))	\
-      && __GLIBC_USE (IEC_60559_TYPES_EXT)
-#  define _Mdouble_ _Float16
-#  define __MATH_DECLARING_DOUBLE 0
-#  define __MATH_DECLARING_FLOATN 1
-#  define __REDIRFROM_X(function, reentrant) \
-  function ## f16 ## reentrant
-#  if __HAVE_DISTINCT_FLOAT16
-#   define __REDIRTO_X(function, reentrant) \
-   __ ## function ## f16 ## reentrant ## _finite
-#  else
-#   error "non-disinct _Float16"
-#  endif
-#  include <bits/math-finite.h>
-#  undef _Mdouble_
-#  undef __MATH_DECLARING_DOUBLE
-#  undef __MATH_DECLARING_FLOATN
-#  undef __REDIRFROM_X
-#  undef __REDIRTO_X
-# endif
-
-# if (__HAVE_DISTINCT_FLOAT32 || (__HAVE_FLOAT32 && !defined _LIBC))	\
-      && __GLIBC_USE (IEC_60559_TYPES_EXT)
-#  define _Mdouble_ _Float32
-#  define __MATH_DECLARING_DOUBLE 0
-#  define __MATH_DECLARING_FLOATN 1
-#  define __REDIRFROM_X(function, reentrant) \
-  function ## f32 ## reentrant
-#  if __HAVE_DISTINCT_FLOAT32
-#   define __REDIRTO_X(function, reentrant) \
-   __ ## function ## f32 ## reentrant ## _finite
-#  else
-#   define __REDIRTO_X(function, reentrant) \
-   __ ## function ## f ## reentrant ## _finite
-#  endif
-#  include <bits/math-finite.h>
-#  undef _Mdouble_
-#  undef __MATH_DECLARING_DOUBLE
-#  undef __MATH_DECLARING_FLOATN
-#  undef __REDIRFROM_X
-#  undef __REDIRTO_X
-# endif
-
-# if (__HAVE_DISTINCT_FLOAT64 || (__HAVE_FLOAT64 && !defined _LIBC))	\
-      && __GLIBC_USE (IEC_60559_TYPES_EXT)
-#  define _Mdouble_ _Float64
-#  define __MATH_DECLARING_DOUBLE 0
-#  define __MATH_DECLARING_FLOATN 1
-#  define __REDIRFROM_X(function, reentrant) \
-  function ## f64 ## reentrant
-#  if __HAVE_DISTINCT_FLOAT64
-#   define __REDIRTO_X(function, reentrant) \
-   __ ## function ## f64 ## reentrant ## _finite
-#  else
-#   define __REDIRTO_X(function, reentrant) \
-   __ ## function ## reentrant ## _finite
-#  endif
-#  include <bits/math-finite.h>
-#  undef _Mdouble_
-#  undef __MATH_DECLARING_DOUBLE
-#  undef __MATH_DECLARING_FLOATN
-#  undef __REDIRFROM_X
-#  undef __REDIRTO_X
-# endif
-
-# if (__HAVE_DISTINCT_FLOAT128 || (__HAVE_FLOAT128 && !defined _LIBC))	\
-      && __GLIBC_USE (IEC_60559_TYPES_EXT)
-#  define _Mdouble_ _Float128
-#  define __MATH_DECLARING_DOUBLE 0
-#  define __MATH_DECLARING_FLOATN 1
-#  define __REDIRFROM_X(function, reentrant) \
-  function ## f128 ## reentrant
-#  if __HAVE_DISTINCT_FLOAT128
-#   define __REDIRTO_X(function, reentrant) \
-   __ ## function ## f128 ## reentrant ## _finite
-#  else
-#   define __REDIRTO_X(function, reentrant) \
-   __ ## function ## l ## reentrant ## _finite
-#  endif
-#  include <bits/math-finite.h>
-#  undef _Mdouble_
-#  undef __MATH_DECLARING_DOUBLE
-#  undef __MATH_DECLARING_FLOATN
-#  undef __REDIRFROM_X
-#  undef __REDIRTO_X
-# endif
-
-# if (__HAVE_DISTINCT_FLOAT32X || (__HAVE_FLOAT32X && !defined _LIBC))	\
-      && __GLIBC_USE (IEC_60559_TYPES_EXT)
-#  define _Mdouble_ _Float32x
-#  define __MATH_DECLARING_DOUBLE 0
-#  define __MATH_DECLARING_FLOATN 1
-#  define __REDIRFROM_X(function, reentrant) \
-  function ## f32x ## reentrant
-#  if __HAVE_DISTINCT_FLOAT32X
-#   define __REDIRTO_X(function, reentrant) \
-   __ ## function ## f32x ## reentrant ## _finite
-#  else
-#   define __REDIRTO_X(function, reentrant) \
-   __ ## function ## reentrant ## _finite
-#  endif
-#  include <bits/math-finite.h>
-#  undef _Mdouble_
-#  undef __MATH_DECLARING_DOUBLE
-#  undef __MATH_DECLARING_FLOATN
-#  undef __REDIRFROM_X
-#  undef __REDIRTO_X
-# endif
-
-# if (__HAVE_DISTINCT_FLOAT64X || (__HAVE_FLOAT64X && !defined _LIBC))	\
-      && __GLIBC_USE (IEC_60559_TYPES_EXT)
-#  define _Mdouble_ _Float64x
-#  define __MATH_DECLARING_DOUBLE 0
-#  define __MATH_DECLARING_FLOATN 1
-#  define __REDIRFROM_X(function, reentrant) \
-  function ## f64x ## reentrant
-#  if __HAVE_DISTINCT_FLOAT64X
-#   define __REDIRTO_X(function, reentrant) \
-   __ ## function ## f64x ## reentrant ## _finite
-#  elif __HAVE_FLOAT64X_LONG_DOUBLE
-#   define __REDIRTO_X(function, reentrant) \
-   __ ## function ## l ## reentrant ## _finite
-#  else
-#   define __REDIRTO_X(function, reentrant) \
-   __ ## function ## f128 ## reentrant ## _finite
-#  endif
-#  include <bits/math-finite.h>
-#  undef _Mdouble_
-#  undef __MATH_DECLARING_DOUBLE
-#  undef __MATH_DECLARING_FLOATN
-#  undef __REDIRFROM_X
-#  undef __REDIRTO_X
-# endif
-
-# if (__HAVE_DISTINCT_FLOAT128X || (__HAVE_FLOAT128X && !defined _LIBC)) \
-      && __GLIBC_USE (IEC_60559_TYPES_EXT)
-#  define _Mdouble_ _Float128x
-#  define __MATH_DECLARING_DOUBLE 0
-#  define __MATH_DECLARING_FLOATN 1
-#  define __REDIRFROM_X(function, reentrant) \
-  function ## f128x ## reentrant
-#  if __HAVE_DISTINCT_FLOAT128X
-#   define __REDIRTO_X(function, reentrant) \
-   __ ## function ## f128x ## reentrant ## _finite
-#  else
-#   error "non-disinct _Float128x"
-#  endif
-#  include <bits/math-finite.h>
-#  undef _Mdouble_
-#  undef __MATH_DECLARING_DOUBLE
-#  undef __MATH_DECLARING_FLOATN
-#  undef __REDIRFROM_X
-#  undef __REDIRTO_X
-# endif
-
-#endif /* __FINITE_MATH_ONLY__ > 0.  */
-
 #if __GLIBC_USE (IEC_60559_BFP_EXT)
 /* An expression whose type has the widest of the evaluation formats
    of X and Y (which are of floating-point types).  */