diff --git a/include/bits/mathcalls-redir.h b/include/bits/mathcalls-redir.h
new file mode 100644
index 0000000000..74a009eb1d
--- /dev/null
+++ b/include/bits/mathcalls-redir.h
@@ -0,0 +1 @@
+#include <math/bits/mathcalls-redir.h>
diff --git a/math/Makefile b/math/Makefile
index ea141cbf99..a1a248a1a4 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -29,7 +29,8 @@ headers		:= math.h bits/mathcalls.h bits/mathinline.h \
 		   bits/libm-simd-decl-stubs.h bits/iscanonical.h \
 		   bits/flt-eval-method.h bits/fp-fast.h bits/fp-logb.h \
 		   bits/long-double.h bits/mathcalls-helper-functions.h \
-		   bits/floatn.h bits/floatn-common.h bits/mathcalls-narrow.h
+		   bits/floatn.h bits/floatn-common.h bits/mathcalls-narrow.h \
+		   bits/mathcalls-redir.h
 
 # FPU support code.
 aux		:= setfpucw fpu_control
diff --git a/math/bits/math-finite.h b/math/bits/math-finite.h
index 0799fe7b29..90dd9d896b 100644
--- a/math/bits/math-finite.h
+++ b/math/bits/math-finite.h
@@ -20,96 +20,33 @@
 # error "Never use <bits/math-finite.h> directly; include <math.h> instead."
 #endif
 
-#define __REDIRFROM(...) __REDIRFROM_X(__VA_ARGS__)
-
-#define __REDIRTO(...) __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
+#define __REDIRFROM_F(...) __REDIRFROM_X(__VA_ARGS__)
 
-/* asin.  */
-__MATH_REDIRCALL (asin, , (_Mdouble_));
+#define __REDIRTO_F(...) __REDIRTO_X(__VA_ARGS__)
 
-/* atan2.  */
-__MATH_REDIRCALL (atan2, , (_Mdouble_, _Mdouble_));
+/* Redirects to a function that is part of the API.  */
+#define __REDIRTO_PUBLIC_F(...) __REDIRTO_PUBLIC_X(__VA_ARGS__)
 
-#if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
-/* atanh.  */
-__MATH_REDIRCALL (atanh, , (_Mdouble_));
-#endif
 
-/* cosh.  */
-__MATH_REDIRCALL (cosh, , (_Mdouble_));
+#define __MATH_REDIR_X(type, from, args, to) \
+  extern type __REDIRECT_NTH (from, args, to)
+#define __MATH_REDIRCALL(function, reentrant, args)		\
+  __MATH_REDIR_X (_Mdouble_,						\
+		  __REDIRFROM_F (function, reentrant), args,	\
+		  __REDIRTO_F (function, reentrant))
 
-/* exp.  */
-__MATH_REDIRCALL (exp, , (_Mdouble_));
+#define __MATH_REDIRCALL_INTERNAL(function, reentrant, args)	\
+  __MATH_REDIR_X (_Mdouble_,						\
+		  __REDIRFROM_F (__CONCAT (__, function),	\
+			       __CONCAT (reentrant, _finite)),	\
+		  args, __REDIRTO_F (function, _r))
 
-#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
-
-#if (__MATH_DECLARING_DOUBLE && (defined __USE_MISC || defined __USE_XOPEN)) \
-    || (!__MATH_DECLARING_DOUBLE && defined __USE_MISC)
-/* j0.  */
-__MATH_REDIRCALL (j0, , (_Mdouble_));
-
-/* y0.  */
-__MATH_REDIRCALL (y0, , (_Mdouble_));
-
-/* j1.  */
-__MATH_REDIRCALL (j1, , (_Mdouble_));
-
-/* y1.  */
-__MATH_REDIRCALL (y1, , (_Mdouble_));
-
-/* jn.  */
-__MATH_REDIRCALL (jn, , (int, _Mdouble_));
-
-/* yn.  */
-__MATH_REDIRCALL (yn, , (int, _Mdouble_));
-#endif
-
-#ifdef __USE_MISC
-/* lgamma_r.  */
-__MATH_REDIRCALL (lgamma, _r, (_Mdouble_, int *));
-#endif
+#define __MATH_REDIR_FINITE 1
+#define __MATH_REDIR_NON_FINITE 0
+#include <bits/mathcalls-redir.h>
+#undef __MATH_REDIR_FINITE
+#undef __MATH_REDIR_NON_FINITE
 
 /* 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 +57,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,30 +72,13 @@ __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 \
@@ -169,29 +89,24 @@ __MATH_REDIRCALL (remainder, , (_Mdouble_, _Mdouble_));
 __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
diff --git a/math/bits/mathcalls-redir.h b/math/bits/mathcalls-redir.h
new file mode 100644
index 0000000000..0f1f325647
--- /dev/null
+++ b/math/bits/mathcalls-redir.h
@@ -0,0 +1,460 @@
+/* Redirections of math functions.
+   Copyright (C) 2018 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/>.  */
+
+/* Functions classified as __MATH_REDIR_FINITE == 1 provide finite
+   implementations.
+   Meanwhile functions classified as __MATH_REDIR_NON_FINITE == 1 do not
+   provide finite implementations.
+   This distinction is required to avoid duplicated redirections when a finite
+   implementation is requested.  */
+
+#ifndef _MATH_H
+# error "Never use <bits/math-redir.h> directly; include <math.h> instead."
+#endif
+
+#define __REDIRFROM(...) __REDIRFROM_X(__VA_ARGS__)
+
+#define __REDIRTO(...) __REDIRTO_X(__VA_ARGS__)
+
+#define __REDIRTO_ALT(...) __REDIRTO_ALT_X(__VA_ARGS__)
+
+/* Floating point types may not have a public API available.  In those cases,
+   functions must be redirected via assembly or via a public API.  */
+
+#define __MATH_REDIR(function, reentrant, args)			\
+  __MATH_REDIR_X (_Mdouble_,					\
+		  __REDIRFROM (function, reentrant), args,	\
+		  __REDIRTO (function, reentrant))
+
+#define __MATH_REDIR_T(type, function, reentrant, args)		\
+  __MATH_REDIR_X (type,						\
+		  __REDIRFROM (function, reentrant), args,	\
+		  __REDIRTO (function, reentrant))
+
+#define __MATH_REDIR_TO_ALT(type, from, reentrant, args, to)	\
+  __MATH_REDIR_X (type,						\
+		  __REDIRFROM (from, reentrant), args,		\
+		  __REDIRTO_ALT (to, reentrant))
+
+#define __MATH_REDIR_ALT(type, function, reentrant, args)	\
+  __MATH_REDIR_X (type,						\
+		  __REDIRFROM (function, reentrant), args,	\
+		  __REDIRTO_ALT (function, reentrant))
+
+/* Helper functions.  */
+
+#if __MATH_REDIR_NON_FINITE == 1
+/* Classify given number.  */
+__MATH_REDIR_TO_ALT (int, __fpclassify,, (_Mdouble_ __value), fpclassify);
+
+/* Test for negative number.  */
+__MATH_REDIR_TO_ALT (int, __signbit,, (_Mdouble_ __value), signbit);
+
+/* Test equality.  */
+__MATH_REDIR_TO_ALT (int, __iseqsig,, (_Mdouble_ __x, _Mdouble_ __y), iseqsig);
+
+/* Test for signaling NaN.  */
+__MATH_REDIR_TO_ALT (int, __issignaling,, (_Mdouble_ __value), issignaling);
+#endif  /* __MATH_REDIR_NON_FINITE == 1  */
+
+
+/* Trigonometric functions.  */
+
+#if __MATH_REDIR_FINITE == 1
+/* Arc cosine of X.  */
+__MATH_REDIR (acos,, (_Mdouble_ __x));
+/* Arc sine of X.  */
+__MATH_REDIR (asin,, (_Mdouble_ __x));
+/* Arc tangent of Y/X.  */
+__MATH_REDIR (atan2,, (_Mdouble_ __y, _Mdouble_ __x));
+#endif  /* __MATH_REDIR_FINITE == 1  */
+
+#if __MATH_REDIR_NON_FINITE == 1
+/* Arc tangent of X.  */
+__MATH_REDIR (atan,, (_Mdouble_ __x));
+/* Cosine of X.  */
+__MATH_REDIR (cos,, (_Mdouble_ __x));
+/* Sine of X.  */
+__MATH_REDIR (sin,, (_Mdouble_ __x));
+/* Tangent of X.  */
+__MATH_REDIR (tan,, (_Mdouble_ __x));
+#endif  /* __MATH_REDIR_NON_FINITE == 1  */
+
+
+/* Hyperbolic functions.  */
+
+#if __MATH_REDIR_FINITE == 1
+/* Hyperbolic cosine of X.  */
+__MATH_REDIR (cosh,, (_Mdouble_ __x));
+/* Hyperbolic sine of X.  */
+__MATH_REDIR (sinh,, (_Mdouble_ __x));
+
+# if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
+/* Hyperbolic arc cosine of X.  */
+__MATH_REDIR (acosh,, (_Mdouble_ __x));
+/* Hyperbolic arc tangent of X.  */
+__MATH_REDIR (atanh,, (_Mdouble_ __x));
+# endif /* defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99 */
+#endif  /* __MATH_REDIR_FINITE == 1  */
+
+#if __MATH_REDIR_NON_FINITE == 1
+# if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
+/* Hyperbolic arc sine of X.  */
+__MATH_REDIR (asinh,, (_Mdouble_ __x));
+# endif
+
+/* Hyperbolic tangent of X.  */
+__MATH_REDIR (tanh,, (_Mdouble_ __x));
+
+# ifdef __USE_GNU
+/* Cosine and sine of X.  */
+__MATH_REDIR_T (void, sincos,,
+		(_Mdouble_ __x, _Mdouble_ *__sinx, _Mdouble_ *__cosx));
+# endif /* defined __USE_GNU  */
+#endif  /* __MATH_REDIR_NON_FINITE == 1  */
+
+
+/* Exponential and logarithmic functions.  */
+
+#if __MATH_REDIR_FINITE == 1
+/* Exponential function of X.  */
+__MATH_REDIR (exp,, (_Mdouble_ __x));
+
+/* Natural logarithm of X.  */
+__MATH_REDIR (log,, (_Mdouble_ __x));
+
+/* Base-ten logarithm of X.  */
+__MATH_REDIR (log10,, (_Mdouble_ __x));
+
+# if __GLIBC_USE (IEC_60559_FUNCS_EXT)
+/* Compute exponent to base ten.  */
+__MATH_REDIR (exp10,, (_Mdouble_ __x));
+# endif  /*__GLIBC_USE (IEC_60559_FUNCS_EXT)  */
+
+# ifdef __USE_ISOC99
+/* Compute base-2 exponential of X.  */
+__MATH_REDIR (exp2,, (_Mdouble_ __x));
+
+/* Compute base-2 logarithm of X.  */
+__MATH_REDIR (log2,, (_Mdouble_ __x));
+# endif  /* defined __USE_ISOC99  */
+#endif  /* __MATH_REDIR_FINITE == 1  */
+
+#if __MATH_REDIR_NON_FINITE == 1
+/* Break VALUE into a normalized fraction and an integral power of 2.  */
+__MATH_REDIR (frexp,, (_Mdouble_ __x, int *__exponent));
+
+/* X times (two to the EXP power).  */
+__MATH_REDIR (ldexp,, (_Mdouble_ __x, int __exponent));
+
+/* Break VALUE into integral and fractional parts.  */
+__MATH_REDIR (modf,, (_Mdouble_ __x, _Mdouble_ *__iptr));
+
+# if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
+/* Return exp(X) - 1.  */
+__MATH_REDIR (expm1,, (_Mdouble_ __x));
+
+/* Return log(1 + X).  */
+__MATH_REDIR (log1p,, (_Mdouble_ __x));
+
+/* Return the base 2 signed integral exponent of X.  */
+__MATH_REDIR (logb,, (_Mdouble_ __x));
+# endif  /* defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99  */
+#endif  /* __MATH_REDIR_NON_FINITE == 1  */
+
+
+/* Power functions.  */
+
+#if __MATH_REDIR_FINITE == 1
+/* Return X to the Y power.  */
+__MATH_REDIR (pow,, (_Mdouble_ __x, _Mdouble_ __y));
+
+/* Return the square root of X.  */
+__MATH_REDIR (sqrt,, (_Mdouble_ __x));
+
+# if defined __USE_XOPEN || defined __USE_ISOC99
+/* Return `sqrt(X*X + Y*Y)'.  */
+__MATH_REDIR (hypot,, (_Mdouble_ __x, _Mdouble_ __y));
+# endif
+#endif  /* __MATH_REDIR_FINITE == 1  */
+
+#if __MATH_REDIR_NON_FINITE == 1
+#if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
+/* Return the cube root of X.  */
+__MATH_REDIR (cbrt,, (_Mdouble_ __x));
+#endif
+#endif  /* __MATH_REDIR_NON_FINITE == 1  */
+
+
+/* Nearest integer, absolute value, and remainder functions.  */
+
+#if __MATH_REDIR_FINITE == 1
+/* Floating-point modulo remainder of X/Y.  */
+__MATH_REDIR (fmod,, (_Mdouble_ __x, _Mdouble_ __y));
+#endif  /* __MATH_REDIR_FINITE == 1  */
+
+#if __MATH_REDIR_NON_FINITE == 1
+/* Smallest integral value not less than X.  */
+__MATH_REDIR (ceil,, (_Mdouble_ __x));
+
+/* Absolute value of X.  */
+__MATH_REDIR (fabs,, (_Mdouble_ __x));
+
+/* Largest integer not greater than X.  */
+__MATH_REDIR (floor,, (_Mdouble_ __x));
+
+# ifdef __USE_MISC
+#  if ((!defined __cplusplus \
+       || __cplusplus < 201103L /* isinf conflicts with C++11.  */ \
+       || __MATH_DECLARING_DOUBLE == 0)) /* isinff or isinfl don't.  */ \
+      && !__MATH_DECLARING_FLOATN
+/* Return 0 if VALUE is finite or NaN, +1 if it
+   is +Infinity, -1 if it is -Infinity.  */
+__MATH_REDIR_ALT (int, isinf,, (_Mdouble_ __value));
+#  endif
+
+#  if !__MATH_DECLARING_FLOATN
+/* Return nonzero if VALUE is finite and not NaN.  */
+__MATH_REDIR_ALT (int, finite,, (_Mdouble_ __value));
+/* Return the remainder of X/Y.  */
+__MATH_REDIR (drem,, (_Mdouble_ __x, _Mdouble_ __y));
+
+/* Return the fractional part of X after dividing out `ilogb (X)'.  */
+__MATH_REDIR (significand,, (_Mdouble_ __x));
+#  endif
+
+# endif /* Use misc.  */
+
+# ifdef __USE_ISOC99
+/* Return X with its signed changed to Y's.  */
+__MATH_REDIR (copysign,, (_Mdouble_ __x, _Mdouble_ __y));
+# endif
+
+# ifdef __USE_ISOC99
+/* Return representation of qNaN for double type.  */
+__MATH_REDIR (nan,, (const char *__tagb));
+# endif
+
+
+# if defined __USE_MISC || (defined __USE_XOPEN && !defined __USE_XOPEN2K)
+#  if ((!defined __cplusplus \
+       || __cplusplus < 201103L /* isnan conflicts with C++11.  */ \
+       || __MATH_DECLARING_DOUBLE == 0)) /* isnanf or isnanl don't.  */ \
+      && !__MATH_DECLARING_FLOATN
+/* Return nonzero if VALUE is not a number.  */
+__MATH_REDIR_ALT (int, isnan,, (_Mdouble_ __value));
+#  endif
+# endif
+#endif  /* __MATH_REDIR_NON_FINITE == 1  */
+
+
+#if __MATH_REDIR_FINITE == 1
+# if defined __USE_MISC || (defined __USE_XOPEN && __MATH_DECLARING_DOUBLE)
+/* Bessel functions.  */
+__MATH_REDIR (j0,, (_Mdouble_));
+__MATH_REDIR (j1,, (_Mdouble_));
+__MATH_REDIR (jn,, (int, _Mdouble_));
+__MATH_REDIR (y0,, (_Mdouble_));
+__MATH_REDIR (y1,, (_Mdouble_));
+__MATH_REDIR (yn,, (int, _Mdouble_));
+# endif
+
+# ifdef __USE_MISC
+/* Reentrant version of lgamma.  This function uses the global variable
+   `signgam'.  The reentrant version instead takes a pointer and stores
+   the value through it.  */
+__MATH_REDIR (lgamma,_r, (_Mdouble_, int *__signgamp));
+# endif
+
+# if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
+/* Return the remainder of integer divison X / Y with infinite precision.  */
+__MATH_REDIR (remainder,, (_Mdouble_ __x, _Mdouble_ __y));
+# endif
+#endif  /* __MATH_REDIR_FINITE == 1  */
+
+
+#if __MATH_REDIR_NON_FINITE == 1
+# if defined __USE_XOPEN || defined __USE_ISOC99
+/* Error and gamma functions.  */
+__MATH_REDIR (erf,, (_Mdouble_));
+__MATH_REDIR (erfc,, (_Mdouble_));
+__MATH_REDIR (lgamma,, (_Mdouble_));
+# endif
+
+# ifdef __USE_ISOC99
+/* True gamma function.  */
+__MATH_REDIR (tgamma,, (_Mdouble_));
+# endif
+
+# if defined __USE_MISC || (defined __USE_XOPEN && !defined __USE_XOPEN2K)
+#  if !__MATH_DECLARING_FLOATN
+/* Obsolete alias for `lgamma'.  */
+__MATH_REDIR (gamma,, (_Mdouble_));
+#  endif
+# endif
+
+
+# if defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99
+/* Return the integer nearest X in the direction of the
+   prevailing rounding mode.  */
+__MATH_REDIR (rint,, (_Mdouble_ __x));
+
+/* Return X + epsilon if X < Y, X - epsilon if X > Y.  */
+__MATH_REDIR (nextafter,, (_Mdouble_ __x, _Mdouble_ __y));
+#  if defined __USE_ISOC99 && !defined __LDBL_COMPAT && !__MATH_DECLARING_FLOATN
+__MATH_REDIR (nexttoward,, (_Mdouble_ __x, long double __y));
+#  endif
+
+#  if __GLIBC_USE (IEC_60559_BFP_EXT) || __MATH_DECLARING_FLOATN
+/* Return X - epsilon.  */
+__MATH_REDIR (nextdown,, (_Mdouble_ __x));
+/* Return X + epsilon.  */
+__MATH_REDIR (nextup,, (_Mdouble_ __x));
+#  endif
+
+#  ifdef __USE_ISOC99
+/* Return X times (2 to the Nth power).  */
+__MATH_REDIR (scalbn,, (_Mdouble_ __x, int __n));
+#  endif
+
+/* Return the binary exponent of X, which must be nonzero.  */
+__MATH_REDIR_T (int, ilogb,, (_Mdouble_ __x));
+# endif
+
+# if __GLIBC_USE (IEC_60559_BFP_EXT) || __MATH_DECLARING_FLOATN
+/* Like ilogb, but returning long int.  */
+__MATH_REDIR_T (long int, llogb,, (_Mdouble_ __x));
+# endif
+
+# ifdef __USE_ISOC99
+/* Return X times (2 to the Nth power).  */
+__MATH_REDIR (scalbln,, (_Mdouble_ __x, long int __n));
+
+/* Round X to integral value in floating-point format using current
+   rounding direction, but do not raise inexact exception.  */
+__MATH_REDIR (nearbyint,, (_Mdouble_ __x));
+
+/* Round X to nearest integral value, rounding halfway cases away from
+   zero.  */
+__MATH_REDIR (round,, (_Mdouble_ __x));
+
+/* Round X to the integral value in floating-point format nearest but
+   not larger in magnitude.  */
+__MATH_REDIR (trunc,, (_Mdouble_ __x));
+
+/* Compute remainder of X and Y and put in *QUO a value with sign of x/y
+   and magnitude congruent `mod 2^n' to the magnitude of the integral
+   quotient x/y, with n >= 3.  */
+__MATH_REDIR (remquo,, (_Mdouble_ __x, _Mdouble_ __y, int *__quo));
+
+
+/* Conversion functions.  */
+
+/* Round X to nearest integral value according to current rounding
+   direction.  */
+__MATH_REDIR_T (long int, lrint,, (_Mdouble_ __x));
+__extension__
+__MATH_REDIR_T (long long int, llrint,, (_Mdouble_ __x));
+
+/* Round X to nearest integral value, rounding halfway cases away from
+   zero.  */
+__MATH_REDIR_T (long int, lround,, (_Mdouble_ __x));
+__extension__
+__MATH_REDIR_T (long long int, llround,, (_Mdouble_ __x));
+
+
+/* Return positive difference between X and Y.  */
+__MATH_REDIR (fdim,, (_Mdouble_ __x, _Mdouble_ __y));
+
+/* Return maximum numeric value from X and Y.  */
+__MATH_REDIR (fmax,, (_Mdouble_ __x, _Mdouble_ __y));
+
+/* Return minimum numeric value from X and Y.  */
+__MATH_REDIR (fmin,, (_Mdouble_ __x, _Mdouble_ __y));
+
+/* Multiply-add function computed as a ternary operation.  */
+__MATH_REDIR (fma,, (_Mdouble_ __x, _Mdouble_ __y, _Mdouble_ __z));
+# endif /* Use ISO C99.  */
+
+# if __GLIBC_USE (IEC_60559_BFP_EXT) || __MATH_DECLARING_FLOATN
+/* Round X to nearest integer value, rounding halfway cases to even.  */
+__MATH_REDIR (roundeven,, (_Mdouble_ __x));
+
+/* Round X to nearest signed integer value, not raising inexact, with
+   control of rounding direction and width of result.  */
+__MATH_REDIR_T (__intmax_t, fromfp,, (_Mdouble_ __x, int __round,
+				      unsigned int __width));
+
+/* Round X to nearest unsigned integer value, not raising inexact,
+   with control of rounding direction and width of result.  */
+__MATH_REDIR_T (__uintmax_t, ufromfp,, (_Mdouble_ __x, int __round,
+					unsigned int __width));
+
+/* Round X to nearest signed integer value, raising inexact for
+   non-integers, with control of rounding direction and width of
+   result.  */
+__MATH_REDIR_T (__intmax_t, fromfpx,, (_Mdouble_ __x, int __round,
+				       unsigned int __width));
+
+/* Round X to nearest unsigned integer value, raising inexact for
+   non-integers, with control of rounding direction and width of
+   result.  */
+__MATH_REDIR_T (__uintmax_t, ufromfpx,, (_Mdouble_ __x, int __round,
+					 unsigned int __width));
+
+/* Return value with maximum magnitude.  */
+__MATH_REDIR (fmaxmag,, (_Mdouble_ __x, _Mdouble_ __y));
+
+/* Return value with minimum magnitude.  */
+__MATH_REDIR (fminmag,, (_Mdouble_ __x, _Mdouble_ __y));
+
+/* Total order operation.  */
+__MATH_REDIR_T (int, totalorder,, (_Mdouble_ __x, _Mdouble_ __y));
+
+/* Total order operation on absolute values.  */
+__MATH_REDIR_T (int, totalordermag,, (_Mdouble_ __x, _Mdouble_ __y));
+
+/* Canonicalize floating-point representation.  */
+__MATH_REDIR_T (int, canonicalize,, (_Mdouble_ *__cx, const _Mdouble_ *__x));
+
+/* Get NaN payload.  */
+__MATH_REDIR (getpayload,, (const _Mdouble_ *__x));
+
+/* Set quiet NaN payload.  */
+__MATH_REDIR_T (int, setpayload,, (_Mdouble_ *__x, _Mdouble_ __payload));
+
+/* Set signaling NaN payload.  */
+__MATH_REDIR_T (int, setpayloadsig,, (_Mdouble_ *__x, _Mdouble_ __payload));
+# endif
+
+# if (defined __USE_MISC || (defined __USE_XOPEN_EXTENDED \
+			    && __MATH_DECLARING_DOUBLE	  \
+			    && !defined __USE_XOPEN2K8))  \
+     && !__MATH_DECLARING_FLOATN
+/* Return X times (2 to the Nth power).  */
+__MATH_REDIR (scalb,, (_Mdouble_ __x, _Mdouble_ __n));
+# endif
+#endif  /* __MATH_REDIR_NON_FINITE == 1  */
+
+#undef __MATH_REDIR
+#undef __MATH_REDIR_T
+#undef __MATH_REDIR_TO_ALT
+#undef __MATH_REDIR_ALT
+#undef __REDIRTO_ALT
+#undef __REDIRTO
+#undef __REDIRFROM
diff --git a/math/math.h b/math/math.h
index ddee4e4083..3edf275e26 100644
--- a/math/math.h
+++ b/math/math.h
@@ -1252,12 +1252,15 @@ iszero (__T __val)
   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.  */
@@ -1271,12 +1274,15 @@ iszero (__T __val)
   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
@@ -1288,9 +1294,13 @@ iszero (__T __val)
 #   ifdef __NO_LONG_DOUBLE_MATH
 #    define __REDIRTO_X(function, reentrant) \
    __ ## function ## reentrant ## _finite
+#    define __REDIRTO_PUBLIC_X(function, reentrant) \
+   __REDIRTO_X(function, reentrant)
 #   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_
@@ -1298,6 +1308,7 @@ iszero (__T __val)
 #   undef __MATH_DECLARING_FLOATN
 #   undef __REDIRFROM_X
 #   undef __REDIRTO_X
+#   undef __REDIRTO_PUBLIC_X
 #  endif
 
 # endif /* __USE_ISOC99.  */
@@ -1314,6 +1325,8 @@ iszero (__T __val)
 #  if __HAVE_DISTINCT_FLOAT16
 #   define __REDIRTO_X(function, reentrant) \
    __ ## function ## f16 ## reentrant ## _finite
+#   define __REDIRTO_PUBLIC_X(function, reentrant) \
+   __REDIRTO_X(function, reentrant)
 #  else
 #   error "non-disinct _Float16"
 #  endif
@@ -1323,6 +1336,7 @@ iszero (__T __val)
 #  undef __MATH_DECLARING_FLOATN
 #  undef __REDIRFROM_X
 #  undef __REDIRTO_X
+#  undef __REDIRTO_PUBLIC_X
 # endif
 
 # if (__HAVE_DISTINCT_FLOAT32 || (__HAVE_FLOAT32 && !defined _LIBC))	\
@@ -1339,12 +1353,15 @@ iszero (__T __val)
 #   define __REDIRTO_X(function, reentrant) \
    __ ## function ## f ## reentrant ## _finite
 #  endif
+#  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
 # endif
 
 # if (__HAVE_DISTINCT_FLOAT64 || (__HAVE_FLOAT64 && !defined _LIBC))	\
@@ -1361,12 +1378,15 @@ iszero (__T __val)
 #   define __REDIRTO_X(function, reentrant) \
    __ ## function ## reentrant ## _finite
 #  endif
+#  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
 # endif
 
 # if (__HAVE_DISTINCT_FLOAT128 || (__HAVE_FLOAT128 && !defined _LIBC))	\
@@ -1379,9 +1399,13 @@ iszero (__T __val)
 #  if __HAVE_DISTINCT_FLOAT128
 #   define __REDIRTO_X(function, reentrant) \
    __ ## function ## f128 ## reentrant ## _finite
+#   define __REDIRTO_PUBLIC_X(function, reentrant) \
+   __REDIRTO_X(function, reentrant)
 #  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_
@@ -1389,6 +1413,7 @@ iszero (__T __val)
 #  undef __MATH_DECLARING_FLOATN
 #  undef __REDIRFROM_X
 #  undef __REDIRTO_X
+#  undef __REDIRTO_PUBLIC_X
 # endif
 
 # if (__HAVE_DISTINCT_FLOAT32X || (__HAVE_FLOAT32X && !defined _LIBC))	\
@@ -1405,12 +1430,15 @@ iszero (__T __val)
 #   define __REDIRTO_X(function, reentrant) \
    __ ## function ## reentrant ## _finite
 #  endif
+#  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
 # endif
 
 # if (__HAVE_DISTINCT_FLOAT64X || (__HAVE_FLOAT64X && !defined _LIBC))	\
@@ -1430,12 +1458,15 @@ iszero (__T __val)
 #   define __REDIRTO_X(function, reentrant) \
    __ ## function ## f128 ## reentrant ## _finite
 #  endif
+#  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
 # endif
 
 # if (__HAVE_DISTINCT_FLOAT128X || (__HAVE_FLOAT128X && !defined _LIBC)) \
@@ -1448,6 +1479,8 @@ iszero (__T __val)
 #  if __HAVE_DISTINCT_FLOAT128X
 #   define __REDIRTO_X(function, reentrant) \
    __ ## function ## f128x ## reentrant ## _finite
+#   define __REDIRTO_PUBLIC_X(function, reentrant) \
+   __REDIRTO_X(function, reentrant)
 #  else
 #   error "non-disinct _Float128x"
 #  endif
@@ -1457,6 +1490,7 @@ iszero (__T __val)
 #  undef __MATH_DECLARING_FLOATN
 #  undef __REDIRFROM_X
 #  undef __REDIRTO_X
+#  undef __REDIRTO_PUBLIC_X
 # endif
 
 #endif /* __FINITE_MATH_ONLY__ > 0.  */
