Patchwork [7/9] Refactor math-finite.h and introduce mathcalls-redir.h

login
register
mail settings
Submitter Tulio Magno Quites Machado Filho
Date June 6, 2018, 10:39 p.m.
Message ID <20180606223909.16675-8-tuliom@linux.ibm.com>
Download mbox | patch
Permalink /patch/27684/
State New
Headers show

Comments

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

This patch moves all of the common redirections done in math-finite.h to
a new header called mathcalls-redir.h.  The new header uses 2 new
macros to classify whether a function should be redirected or not:

 - __MATH_REDIR_FINITE: redirects the functions that are part of the
   finite ABI when set to 1.
 - __MATH_REDIR_NON_FINITE: redirects all the other math functions when
   set to 1.

With this mechanism, math-finite.h can redirect its functions by using
__MATH_REDIR_FINITE = 1 and __MATH_REDIR_NON_FINITE = 0.

mathcalls-redir.h also provides alternative redirection destinations in
order to support functions that should not be redirected
to the same name pattern of the rest of the functions, i.e.:
__fpclassify, __signbit, __iseqsig, __issignaling, isinf, finite and
isnan, which will be redirected to __*f128 instead of __*ieee128 used
for the rest.

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-06  Tulio Magno Quites Machado Filho  <tuliom@linux.ibm.com>

	* include/bits/mathcalls-redir.h: New file
	* math/Makefile (headers): Add bits/mathcalls-redir.h.
	* math/bits/math-finite.h: Move most of the functions to
	bits/mathcalls-redir.h.
	* math/bits/mathcalls-redir.h: New file.
	* math/math.h: Define __REDIRTO_PUBLIC_X before including
	bits/math-finite.h.  Undefine it afterwards.

Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
---
 include/bits/mathcalls-redir.h |   1 +
 math/Makefile                  |   3 +-
 math/bits/math-finite.h        | 151 +++-----------
 math/bits/mathcalls-redir.h    | 460 +++++++++++++++++++++++++++++++++++++++++
 math/math.h                    |  34 +++
 5 files changed, 530 insertions(+), 119 deletions(-)
 create mode 100644 include/bits/mathcalls-redir.h
 create mode 100644 math/bits/mathcalls-redir.h
Joseph Myers - June 6, 2018, 11:23 p.m.
On Wed, 6 Jun 2018, Tulio Magno Quites Machado Filho wrote:

> On a new enough compiler, redirecting the same function twice can cause
> -Werror=pragmas errors.  This issue may appear when redirecting an ISO C
> floating point function to a different ABI at the same time that finite
> redirections are expected.

Does this issue already appear with -mlong-double-64?  If so, it should 
definitely be separated out from this patch series and have a bug filed in 
Bugzilla as usual for anything fixing a bug that was user-visible in a 
release.

The approach taken in this patch involves a lot of duplication of both 
function prototypes and the feature-test-macro conditions on when those 
functions are declared (duplicating them for functions not included in 
math-finite.h, when previously only those in math-finite.h had such 
duplication).  Such duplication is, from experience, fragile and a bad 
idea; the conditions and declarations are too likely to get out of sync.

Instead, I'd suggest merging bits/math-finite.h into bits/mathcalls.h as 
much as possible - have macros such as __MATHCALL_FINITE that are called 
in bits/mathcalls.h to declare the functions with __*_finite variants, and 
with __MATHCALL_FINITE defined the same as __MATHCALL when the finite 
function variants aren't in use.  That way you have just a single 
redirection for each function.  (You'll need a sysdeps bits/ header for an 
architecture, i.e. ia64, to declare it doesn't support the _finite 
functions at all.)
Tulio Magno Quites Machado Filho - June 13, 2018, 9:35 p.m.
Joseph Myers <joseph@codesourcery.com> writes:

> On Wed, 6 Jun 2018, Tulio Magno Quites Machado Filho wrote:
>
>> On a new enough compiler, redirecting the same function twice can cause
>> -Werror=pragmas errors.  This issue may appear when redirecting an ISO C
>> floating point function to a different ABI at the same time that finite
>> redirections are expected.
>
> Does this issue already appear with -mlong-double-64?  If so, it should 
> definitely be separated out from this patch series and have a bug filed in 
> Bugzilla as usual for anything fixing a bug that was user-visible in a 
> release.

Yes, I can reproduce it in our tests if I replace -mlong-double-128 with
-mlong-double-64.
However, this is not user-visible because this warning is ignored in system
headers.

Do you still think a bug report is necessary?

> The approach taken in this patch involves a lot of duplication of both 
> function prototypes and the feature-test-macro conditions on when those 
> functions are declared (duplicating them for functions not included in 
> math-finite.h, when previously only those in math-finite.h had such 
> duplication).  Such duplication is, from experience, fragile and a bad 
> idea; the conditions and declarations are too likely to get out of sync.

Agreed.

> Instead, I'd suggest merging bits/math-finite.h into bits/mathcalls.h as 
> much as possible - have macros such as __MATHCALL_FINITE that are called 
> in bits/mathcalls.h to declare the functions with __*_finite variants, and 
> with __MATHCALL_FINITE defined the same as __MATHCALL when the finite 
> function variants aren't in use.  That way you have just a single 
> redirection for each function.  (You'll need a sysdeps bits/ header for an 
> architecture, i.e. ia64, to declare it doesn't support the _finite 
> functions at all.)

It doesn't work well this way because we have prototypes with extra attributes,
e.g:

__MATHDECL_1 (int, totalorder,, (_Mdouble_ __x, _Mdouble_ __y))
     __attribute__ ((__const__));

So, if I do not define __MATHDECL_1 in bits/math-finite.h, this code would end
up as an invalid code:

__attribute__ ((__const__));

I managed to remove bits/math-redir.h and modified both math.h and
bits/math-finite.h to reuse bits/mathcalls.h.  I had to keep using
__MATH_DECLARE_FINITE and __MATH_DECLARE_NON_FINITE.

Would this be acceptable?
Joseph Myers - June 13, 2018, 10:58 p.m.
On Wed, 13 Jun 2018, Tulio Magno Quites Machado Filho wrote:

> Yes, I can reproduce it in our tests if I replace -mlong-double-128 with
> -mlong-double-64.
> However, this is not user-visible because this warning is ignored in system
> headers.
> 
> Do you still think a bug report is necessary?

I think we want to be clean with -Wsystem-headers; thus, there should be a 
bug report.

> > Instead, I'd suggest merging bits/math-finite.h into bits/mathcalls.h as 
> > much as possible - have macros such as __MATHCALL_FINITE that are called 
> > in bits/mathcalls.h to declare the functions with __*_finite variants, and 
> > with __MATHCALL_FINITE defined the same as __MATHCALL when the finite 
> > function variants aren't in use.  That way you have just a single 
> > redirection for each function.  (You'll need a sysdeps bits/ header for an 
> > architecture, i.e. ia64, to declare it doesn't support the _finite 
> > functions at all.)
> 
> It doesn't work well this way because we have prototypes with extra attributes,
> e.g:
> 
> __MATHDECL_1 (int, totalorder,, (_Mdouble_ __x, _Mdouble_ __y))
>      __attribute__ ((__const__));
> 
> So, if I do not define __MATHDECL_1 in bits/math-finite.h, this code would end
> up as an invalid code:
> 
> __attribute__ ((__const__));

My proposal is that bits/math-finite.h either shouldn't exist or should 
end up just defining the lgamma / gamma / tgamma inlines.  
bits/mathcalls.h would be included once per type, with the macros 
definitions in effect when it's included depending on "defined 
__FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0" (so if that's true some 
functions would be redirected to __*finite versions, if that's false it 
would behave much as it does at present).
Tulio Magno Quites Machado Filho - June 14, 2018, 6:07 p.m.
Joseph Myers <joseph@codesourcery.com> writes:

> On Wed, 13 Jun 2018, Tulio Magno Quites Machado Filho wrote:
>
>> Yes, I can reproduce it in our tests if I replace -mlong-double-128 with
>> -mlong-double-64.
>> However, this is not user-visible because this warning is ignored in system
>> headers.
>> 
>> Do you still think a bug report is necessary?
>
> I think we want to be clean with -Wsystem-headers; thus, there should be a 
> bug report.

Ack.
Reported as https://sourceware.org/bugzilla/show_bug.cgi?id=23292

>> > Instead, I'd suggest merging bits/math-finite.h into bits/mathcalls.h as 
>> > much as possible - have macros such as __MATHCALL_FINITE that are called 
>> > in bits/mathcalls.h to declare the functions with __*_finite variants, and 
>> > with __MATHCALL_FINITE defined the same as __MATHCALL when the finite 
>> > function variants aren't in use.  That way you have just a single 
>> > redirection for each function.  (You'll need a sysdeps bits/ header for an 
>> > architecture, i.e. ia64, to declare it doesn't support the _finite 
>> > functions at all.)
>> 
>> It doesn't work well this way because we have prototypes with extra attributes,
>> e.g:
>> 
>> __MATHDECL_1 (int, totalorder,, (_Mdouble_ __x, _Mdouble_ __y))
>>      __attribute__ ((__const__));
>> 
>> So, if I do not define __MATHDECL_1 in bits/math-finite.h, this code would end
>> up as an invalid code:
>> 
>> __attribute__ ((__const__));
>
> My proposal is that bits/math-finite.h either shouldn't exist or should 
> end up just defining the lgamma / gamma / tgamma inlines.  
> bits/mathcalls.h would be included once per type, with the macros 
> definitions in effect when it's included depending on "defined 
> __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0" (so if that's true some 
> functions would be redirected to __*finite versions, if that's false it 
> would behave much as it does at present).

Interesting...
I'm working on this.

Patch

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.  */