diff --git a/include/math.h b/include/math.h
index e21d34b868..57d77cfd13 100644
--- a/include/math.h
+++ b/include/math.h
@@ -18,7 +18,9 @@ hidden_proto (__finitef)
 hidden_proto (__isinff)
 hidden_proto (__isnanf)
 
-#  ifndef __NO_LONG_DOUBLE_MATH
+#  if !defined __NO_LONG_DOUBLE_MATH \
+      && (!__HAVE_DISTINCT_FLOAT128 \
+	  || (__HAVE_DISTINCT_FLOAT128 && __HAVE_FLOAT128_UNLIKE_LDBL))
 hidden_proto (__finitel)
 hidden_proto (__isinfl)
 hidden_proto (__isnanl)
@@ -40,7 +42,9 @@ libm_hidden_proto (__exp)
 libm_hidden_proto (__expf)
 libm_hidden_proto (__roundeven)
 
-# ifndef __NO_LONG_DOUBLE_MATH
+#  if !defined __NO_LONG_DOUBLE_MATH \
+  && (!__HAVE_DISTINCT_FLOAT128 \
+      || (__HAVE_DISTINCT_FLOAT128 && __HAVE_FLOAT128_UNLIKE_LDBL))
 libm_hidden_proto (__fpclassifyl)
 libm_hidden_proto (__issignalingl)
 libm_hidden_proto (__expl)
@@ -61,7 +65,11 @@ libm_hidden_proto (__expm1f128)
 float (sqrtf) (float) asm ("__ieee754_sqrtf");
 double (sqrt) (double) asm ("__ieee754_sqrt");
 #   ifndef __NO_LONG_DOUBLE_MATH
+/* Do not redirect sqrtl twice when the long double already redirects it.  */
+#    if !__HAVE_DISTINCT_FLOAT128 \
+	|| (__HAVE_DISTINCT_FLOAT128 && __HAVE_FLOAT128_UNLIKE_LDBL)
 long double (sqrtl) (long double) asm ("__ieee754_sqrtl");
+#    endif
 #   endif
 #   if __HAVE_DISTINCT_FLOAT128 > 0
 _Float128 (sqrtf128) (_Float128) asm ("__ieee754_sqrtf128");
diff --git a/math/bits/mathcalls-helper-functions.h b/math/bits/mathcalls-helper-functions.h
index ac3115bfdc..a6d83bf4e6 100644
--- a/math/bits/mathcalls-helper-functions.h
+++ b/math/bits/mathcalls-helper-functions.h
@@ -16,28 +16,30 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-
 /* Classify given number.  */
-__MATHDECL_1 (int, __fpclassify,, (_Mdouble_ __value))
+__MATHDECL_ALIAS (int, __fpclassify,, (_Mdouble_ __value), fpclassify)
      __attribute__ ((__const__));
 
 /* Test for negative number.  */
-__MATHDECL_1 (int, __signbit,, (_Mdouble_ __value))
+__MATHDECL_ALIAS (int, __signbit,, (_Mdouble_ __value), signbit)
      __attribute__ ((__const__));
 
 /* Return 0 if VALUE is finite or NaN, +1 if it
    is +Infinity, -1 if it is -Infinity.  */
-__MATHDECL_1 (int, __isinf,, (_Mdouble_ __value)) __attribute__ ((__const__));
+__MATHDECL_ALIAS (int, __isinf,, (_Mdouble_ __value), isinf)
+  __attribute__ ((__const__));
 
 /* Return nonzero if VALUE is finite and not NaN.  Used by isfinite macro.  */
-__MATHDECL_1 (int, __finite,, (_Mdouble_ __value)) __attribute__ ((__const__));
+__MATHDECL_ALIAS (int, __finite,, (_Mdouble_ __value), finite)
+  __attribute__ ((__const__));
 
 /* Return nonzero if VALUE is not a number.  */
-__MATHDECL_1 (int, __isnan,, (_Mdouble_ __value)) __attribute__ ((__const__));
+__MATHDECL_ALIAS (int, __isnan,, (_Mdouble_ __value), isnan)
+  __attribute__ ((__const__));
 
 /* Test equality.  */
-__MATHDECL_1 (int, __iseqsig,, (_Mdouble_ __x, _Mdouble_ __y));
+__MATHDECL_ALIAS (int, __iseqsig,, (_Mdouble_ __x, _Mdouble_ __y), iseqsig);
 
 /* Test for signaling NaN.  */
-__MATHDECL_1 (int, __issignaling,, (_Mdouble_ __value))
+__MATHDECL_ALIAS (int, __issignaling,, (_Mdouble_ __value), issignaling)
      __attribute__ ((__const__));
diff --git a/math/bits/mathcalls.h b/math/bits/mathcalls.h
index f4246a7881..9ace71bef6 100644
--- a/math/bits/mathcalls.h
+++ b/math/bits/mathcalls.h
@@ -173,12 +173,14 @@ __MATHCALL_FINITE (fmod,, (_Mdouble_ __x, _Mdouble_ __y));
       && !__MATH_DECLARING_FLOATN
 /* Return 0 if VALUE is finite or NaN, +1 if it
    is +Infinity, -1 if it is -Infinity.  */
-__MATHDECL_1 (int,isinf,, (_Mdouble_ __value)) __attribute__ ((__const__));
+__MATHDECL_ALIAS (int,isinf,, (_Mdouble_ __value), isinf)
+  __attribute__ ((__const__));
 # endif
 
 # if !__MATH_DECLARING_FLOATN
 /* Return nonzero if VALUE is finite and not NaN.  */
-__MATHDECL_1 (int,finite,, (_Mdouble_ __value)) __attribute__ ((__const__));
+__MATHDECL_ALIAS (int,finite,, (_Mdouble_ __value), finite)
+  __attribute__ ((__const__));
 
 /* Return the remainder of X/Y.  */
 __MATHCALL (drem,, (_Mdouble_ __x, _Mdouble_ __y));
@@ -207,7 +209,8 @@ __MATHCALL (nan,, (const char *__tagb));
        || __MATH_DECLARING_DOUBLE == 0)) /* isnanf or isnanl don't.  */ \
       && !__MATH_DECLARING_FLOATN
 /* Return nonzero if VALUE is not a number.  */
-__MATHDECL_1 (int,isnan,, (_Mdouble_ __value)) __attribute__ ((__const__));
+__MATHDECL_ALIAS (int,isnan,, (_Mdouble_ __value), isnan)
+  __attribute__ ((__const__));
 # endif
 #endif
 
diff --git a/math/math.h b/math/math.h
index c1765e4c8c..8d0880b262 100644
--- a/math/math.h
+++ b/math/math.h
@@ -283,6 +283,10 @@ enum
   extern type __MATH_PRECNAME(function,suffix) args __THROW
 #define __MATHDECL_1(type, function, suffix, args) \
   __MATHDECL_1_IMPL(type, function, suffix, args)
+/* Ignore the alias by default.  The alias is only useful with
+   redirections.  */
+#define __MATHDECL_ALIAS(type, function, suffix, args, alias) \
+  __MATHDECL_1_IMPL(type, function, suffix, args)
 
 #define __MATHREDIR(type, function, suffix, args, to) \
   extern type __REDIRECT_NTH (__MATH_PRECNAME (function, suffix), args, to)
@@ -364,6 +368,39 @@ extern long double __REDIRECT_NTH (nexttowardl,
 #   undef __MATHDECL_1
 #   define __MATHDECL_1(type, function,suffix, args) \
   __MATHREDIR(type, function, suffix, args, __CONCAT(function,suffix))
+
+#  elif __HAVE_DISTINCT_FLOAT128 && !__HAVE_FLOAT128_UNLIKE_LDBL
+#   ifdef __REDIRECT_NTH
+#    ifdef __USE_ISOC99
+extern float __REDIRECT_NTH (nexttowardf, (float __x, long double __y),
+			    __nexttowardf_to_ieee128)
+  __attribute__ ((__const__));
+extern double __REDIRECT_NTH (nexttoward, (double __x, long double __y),
+			     __nexttoward_to_ieee128)
+  __attribute__ ((__const__));
+
+#define __dremieee128 __remainderieee128
+#define __gammaieee128 __lgammaieee128
+
+#    endif
+#   endif
+
+#   undef __MATHDECL_1
+#   undef __MATHDECL_ALIAS
+
+#   define __REDIRTO(function, suffix) \
+  __ ## function ## ieee128 ## suffix
+#   define __REDIRTO_ALT(function, suffix) \
+  __ ## function ## f128 ## suffix
+
+#   undef __MATH_FINITE_NAME
+#   define __MATH_FINITE_NAME(function, suffix) \
+  __MATH_FINITE_NAMEX (, __REDIRTO_ALT (function, suffix), _finite)
+
+#   define __MATHDECL_1(type, function, suffix, args) \
+  __MATHREDIR (type, function, suffix, args, __REDIRTO (function, suffix))
+#   define __MATHDECL_ALIAS(type, function, suffix, args, alias) \
+  __MATHREDIR (type, function, suffix, args, __REDIRTO_ALT (alias, suffix))
 #  endif
 
 /* Include the file of declarations again, this time using `long double'
@@ -376,15 +413,25 @@ extern long double __REDIRECT_NTH (nexttowardl,
 #  define __MATH_DECLARE_LDOUBLE   1
 #  include <bits/mathcalls-helper-functions.h>
 #  include <bits/mathcalls.h>
+
 #  undef _Mdouble_
 #  undef __MATH_PRECNAME
 #  undef __MATH_DECLARING_DOUBLE
 #  undef __MATH_DECLARING_FLOATN
 
-#  if defined __LDBL_COMPAT
+#  if defined __LDBL_COMPAT \
+      || (__HAVE_DISTINCT_FLOAT128 && !__HAVE_FLOAT128_UNLIKE_LDBL)
+#   undef __REDIRTO
+#   undef __REDIRTO_ALT
 #   undef __MATHDECL_1
+#   undef __MATHDECL_ALIAS
+#   undef __MATH_FINITE_NAME
+#   define __MATH_FINITE_NAME(function, suffix) \
+  __MATH_FINITE_NAME_IMPL (function, suffix)
 #   define __MATHDECL_1(type, function, suffix, args) \
   __MATHDECL_1_IMPL(type, function, suffix, args)
+#   define __MATHDECL_ALIAS(type, function, suffix, args, alias) \
+  __MATHDECL_1_IMPL(type, function, suffix, args)
 #  endif
 # endif /* !(__NO_LONG_DOUBLE_MATH && _LIBC) || __LDBL_COMPAT */
 
@@ -720,6 +767,7 @@ extern int signgam;
 #undef	__REDIRTO_PUBLIC_X
 #undef	__MATHDECL_1_IMPL
 #undef	__MATHDECL_1
+#undef	__MATHDECL_ALIAS
 #undef	__MATHDECL
 #undef	__MATHCALL
 #undef	__MATHCALL_VEC
@@ -759,6 +807,11 @@ extern int signgam;
 # ifdef __LDBL_COMPAT
 #  define __MATHCALL_REDIR_NAME(name) f ## name
 #  undef __MATHCALL_NARROW
+#  define __MATHCALL_NARROW(func, redir, nargs) \
+  __MATHCALL_NARROW_REDIR (func, redir, nargs)
+# elif __HAVE_DISTINCT_FLOAT128 && !__HAVE_FLOAT128_UNLIKE_LDBL
+#  define __MATHCALL_REDIR_NAME(name) __ ## f32 ## name ## ieee128
+#  undef __MATHCALL_NARROW
 #  define __MATHCALL_NARROW(func, redir, nargs) \
   __MATHCALL_NARROW_REDIR (func, redir, nargs)
 # endif
@@ -766,7 +819,8 @@ extern int signgam;
 # undef _Mret_
 # undef _Marg_
 # undef __MATHCALL_NAME
-# ifdef __LDBL_COMPAT
+# if defined __LDBL_COMPAT \
+     || (__HAVE_DISTINCT_FLOAT128 && !__HAVE_FLOAT128_UNLIKE_LDBL)
 #  undef __MATHCALL_REDIR_NAME
 #  undef __MATHCALL_NARROW
 #  define __MATHCALL_NARROW(func, redir, nargs) \
@@ -779,6 +833,11 @@ extern int signgam;
 # ifdef __LDBL_COMPAT
 #  define __MATHCALL_REDIR_NAME(name) __nldbl_d ## name ## l
 #  undef __MATHCALL_NARROW
+#  define __MATHCALL_NARROW(func, redir, nargs) \
+  __MATHCALL_NARROW_REDIR (func, redir, nargs)
+# elif __HAVE_DISTINCT_FLOAT128 && !__HAVE_FLOAT128_UNLIKE_LDBL
+#  define __MATHCALL_REDIR_NAME(name) __ ## f64 ## name ## ieee128
+#  undef __MATHCALL_NARROW
 #  define __MATHCALL_NARROW(func, redir, nargs) \
   __MATHCALL_NARROW_REDIR (func, redir, nargs)
 # endif
@@ -786,7 +845,8 @@ extern int signgam;
 # undef _Mret_
 # undef _Marg_
 # undef __MATHCALL_NAME
-# ifdef __LDBL_COMPAT
+# if defined __LDBL_COMPAT \
+     || (__HAVE_DISTINCT_FLOAT128 && !__HAVE_FLOAT128_UNLIKE_LDBL)
 #  undef __MATHCALL_REDIR_NAME
 #  undef __MATHCALL_NARROW
 #  define __MATHCALL_NARROW(func, redir, nargs) \
diff --git a/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h b/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h
index 60c54cca46..f54e5d9ddb 100644
--- a/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h
+++ b/sysdeps/ieee754/ldbl-128ibm/bits/iscanonical.h
@@ -50,7 +50,11 @@ extern "C++" {
 inline int iscanonical (float __val) { return __iscanonicalf (__val); }
 inline int iscanonical (double __val) { return __iscanonical (__val); }
 inline int iscanonical (long double __val) { return __iscanonicall (__val); }
-#  if __HAVE_DISTINCT_FLOAT128
+/* When using an IEEE 128-bit long double, _Float128 is defined as long double
+   in C++.  */
+#  if __HAVE_DISTINCT_FLOAT128 \
+      && (!defined __cplusplus \
+	  || defined __cplusplus && __HAVE_FLOAT128_UNLIKE_LDBL)
 inline int iscanonical (_Float128 __val) { return __iscanonicalf128 (__val); }
 #  endif
 }
