diff --git a/NEWS b/NEWS
index ea1a0e0..2da72cd 100644
--- a/NEWS
+++ b/NEWS
@@ -58,6 +58,8 @@ Version 2.25
   - Total order functions: totalorder, totalorderf, totalorderl,
     totalordermag, totalordermagf, totalordermagl.
 
+  - Canonicalize functions: canonicalize, canonicalizef, canonicalizel.
+
   - NaN functions: getpayload, getpayloadf, getpayloadl.
 
 * The functions strfromd, strfromf, and strfroml, from ISO/IEC TS 18661-1:2014,
diff --git a/manual/arith.texi b/manual/arith.texi
index eaaf2b7..a5c04e4 100644
--- a/manual/arith.texi
+++ b/manual/arith.texi
@@ -1857,6 +1857,36 @@ selects one.  On other systems it may do nothing.
 
 @comment math.h
 @comment ISO
+@deftypefun int canonicalize (double *@var{cx}, const double *@var{x})
+@comment math.h
+@comment ISO
+@deftypefunx int canonicalizef (float *@var{cx}, const float *@var{x})
+@comment math.h
+@comment ISO
+@deftypefunx int canonicalizel (long double *@var{cx}, const long double *@var{x})
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+In some floating-point formats, some values have canonical (preferred)
+and noncanonical encodings (for IEEE interchange binary formats, all
+encodings are canonical).  These functions, defined by TS
+18661-1:2014, attempt to produce a canonical version of the
+floating-point value pointed to by @var{x}; if that value is a
+signaling NaN, they raise the invalid exception and produce a quiet
+NaN.  If a canonical value is produced, it is stored in the object
+pointed to by @var{cx}, and these functions return zero.  Otherwise
+(if a canonical value could not be produced because the object pointed
+to by @var{x} is not a valid representation of any floating-point
+value), the object pointed to by @var{cx} is unchanged and a nonzero
+value is returned.
+
+Note that some formats have multiple encodings of a value which are
+all equally canonical; when such an encoding is used as an input to
+this function, any such encoding of the same value (or of the
+corresponding quiet NaN, if that value is a signaling NaN) may be
+produced as output.
+@end deftypefun
+
+@comment math.h
+@comment ISO
 @deftypefun double getpayload (const double *@var{x})
 @comment math.h
 @comment ISO
diff --git a/manual/libm-err-tab.pl b/manual/libm-err-tab.pl
index 59c5372..18b8ca9 100755
--- a/manual/libm-err-tab.pl
+++ b/manual/libm-err-tab.pl
@@ -77,10 +77,10 @@ use vars qw (%results @all_floats %suffices @all_functions);
     "nextup", "pow", "remainder", "remquo", "rint", "round", "scalb",
     "scalbn", "sin", "sincos", "sinh", "sqrt", "tan", "tanh", "tgamma",
     "trunc", "y0", "y1", "yn" );
-# fpclassify, getpayload, iscanonical, isnormal, isfinite, isinf, isnan,
-# issignaling, issubnormal, iszero, signbit, iseqsig, isgreater,
-# isgreaterequal, isless, islessequal, islessgreater, isunordered,
-# totalorder, totalordermag
+# canonicalize, fpclassify, getpayload, iscanonical, isnormal,
+# isfinite, isinf, isnan, issignaling, issubnormal, iszero, signbit,
+# iseqsig, isgreater, isgreaterequal, isless, islessequal,
+# islessgreater, isunordered, totalorder, totalordermag
 # are not tabulated.
 
 if ($#ARGV == 0) {
diff --git a/math/Makefile b/math/Makefile
index 7cecba5..f400d7b 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -51,7 +51,7 @@ gen-libm-calls = cargF conjF cimagF crealF cabsF s_cacosF		  \
 		 k_casinhF s_csinhF k_casinhF s_csinhF s_catanhF s_catanF \
 		 s_ctanF s_ctanhF s_cexpF s_clogF s_cprojF s_csqrtF	  \
 		 s_cpowF s_clog10F s_fdimF s_nextdownF s_fmaxF s_fminF	  \
-		 s_nanF s_iseqsigF
+		 s_nanF s_iseqsigF s_canonicalizeF
 
 libm-calls =								  \
 	e_acosF e_acoshF e_asinF e_atan2F e_atanhF e_coshF e_expF e_fmodF \
diff --git a/math/Versions b/math/Versions
index a2e0d90..0cd594b 100644
--- a/math/Versions
+++ b/math/Versions
@@ -220,5 +220,6 @@ libm {
     totalorder; totalorderf; totalorderl;
     totalordermag; totalordermagf; totalordermagl;
     getpayload; getpayloadf; getpayloadl;
+    canonicalize; canonicalizef; canonicalizel;
   }
 }
diff --git a/math/bits/mathcalls.h b/math/bits/mathcalls.h
index c5853a3..2fd1d28 100644
--- a/math/bits/mathcalls.h
+++ b/math/bits/mathcalls.h
@@ -395,6 +395,9 @@ __MATHDECL_1 (int, totalorder,, (_Mdouble_ __x, _Mdouble_ __y))
 __MATHDECL_1 (int, totalordermag,, (_Mdouble_ __x, _Mdouble_ __y))
      __attribute__ ((__const__));
 
+/* Canonicalize floating-point representation.  */
+__MATHDECL_1 (int, canonicalize,, (_Mdouble_ *__cx, const _Mdouble_ *__x));
+
 /* Get NaN payload.  */
 __MATHCALL (getpayload,, (const _Mdouble_ *__x));
 #endif
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 89e0e59..7106338 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -43,7 +43,8 @@
 
 /* This testsuite has currently tests for:
    acos, acosh, asin, asinh, atan, atan2, atanh,
-   cbrt, ceil, copysign, cos, cosh, drem, erf, erfc, exp, exp10, exp2, expm1,
+   canonicalize, cbrt, ceil, copysign, cos, cosh, drem,
+   erf, erfc, exp, exp10, exp2, expm1,
    fabs, fdim, finite, floor, fma, fmax, fmin, fmod, fpclassify,
    frexp, gamma, getpayload, hypot,
    ilogb, iscanonical, isfinite, isinf, isnan, isnormal, issignaling,
@@ -85,8 +86,9 @@
    against.  These implemented tests should check all cases that are
    specified in ISO C99.
 
-   NaN values: The payload of NaNs is not examined, but is set in
-   inputs for functions where it is significant.
+   NaN values: The payload of NaNs is set in inputs for functions
+   where it is significant, and is examined in the outputs of some
+   functions.
 
    Inline functions: Inlining functions should give an improvement in
    speed - but not in precission.  The inlined functions return
@@ -172,17 +174,22 @@
 /* Some special test flags, passed together with exceptions.  */
 #define IGNORE_ZERO_INF_SIGN		0x400
 #define TEST_NAN_SIGN			0x800
-#define NO_TEST_INLINE			0x1000
-#define XFAIL_TEST			0x2000
+#define TEST_NAN_PAYLOAD		0x1000
+#define NO_TEST_INLINE			0x2000
+#define XFAIL_TEST			0x4000
 /* Indicate errno settings required or disallowed.  */
-#define ERRNO_UNCHANGED			0x4000
-#define ERRNO_EDOM			0x8000
-#define ERRNO_ERANGE			0x10000
+#define ERRNO_UNCHANGED			0x8000
+#define ERRNO_EDOM			0x10000
+#define ERRNO_ERANGE			0x20000
 /* Flags generated by gen-libm-test.pl, not entered here manually.  */
-#define IGNORE_RESULT			0x20000
-#define NON_FINITE			0x40000
-#define TEST_SNAN			0x80000
-#define NO_TEST_MATHVEC			0x100000
+#define IGNORE_RESULT			0x40000
+#define NON_FINITE			0x80000
+#define TEST_SNAN			0x100000
+#define NO_TEST_MATHVEC			0x200000
+
+#define TEST_NAN_PAYLOAD_CANONICALIZE	(SNAN_TESTS_PRESERVE_PAYLOAD	\
+					 ? TEST_NAN_PAYLOAD		\
+					 : 0)
 
 #define __CONCATX(a,b) __CONCAT(a,b)
 
@@ -801,6 +808,13 @@ check_float_internal (const char *test_name, FLOAT computed, FLOAT expected,
 	  ok = 0;
 	  printf ("signaling NaN has wrong sign.\n");
 	}
+      else if ((exceptions & TEST_NAN_PAYLOAD) != 0
+	       && (FUNC (getpayload) (&computed)
+		   != FUNC (getpayload) (&expected)))
+	{
+	  ok = 0;
+	  printf ("signaling NaN has wrong payload.\n");
+	}
       else
 	ok = 1;
     }
@@ -814,6 +828,13 @@ check_float_internal (const char *test_name, FLOAT computed, FLOAT expected,
 	  ok = 0;
 	  printf ("quiet NaN has wrong sign.\n");
 	}
+      else if ((exceptions & TEST_NAN_PAYLOAD) != 0
+	       && (FUNC (getpayload) (&computed)
+		   != FUNC (getpayload) (&expected)))
+	{
+	  ok = 0;
+	  printf ("quiet NaN has wrong payload.\n");
+	}
       else
 	ok = 1;
     }
@@ -1277,6 +1298,18 @@ struct test_fFF_11_data
     FLOAT extra2_expected;
   } rd, rn, rz, ru;
 };
+struct test_Ffp_b1_data
+{
+  const char *arg_str;
+  FLOAT arg;
+  struct
+  {
+    int expected;
+    int exceptions;
+    int extra_test;
+    FLOAT extra_expected;
+  } rd, rn, rz, ru;
+};
 
 /* Set the rounding mode, or restore the saved value.  */
 #define IF_ROUND_INIT_	/* Empty.  */
@@ -1550,6 +1583,36 @@ struct test_fFF_11_data
 			    (ARRAY)[i].RM_##ROUNDING_MODE.extra_test,	\
 			    (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \
   ROUND_RESTORE_ ## ROUNDING_MODE
+#define RUN_TEST_Ffp_b1(ARG_STR, FUNC_NAME, ARG, EXPECTED,		\
+			EXCEPTIONS, EXTRA_VAR, EXTRA_TEST,		\
+			EXTRA_EXPECTED)					\
+  do									\
+    if (enable_test (EXCEPTIONS))					\
+      {									\
+	COMMON_TEST_SETUP (ARG_STR);					\
+	(EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0;			\
+	check_bool (test_name, FUNC_TEST (FUNC_NAME) (&(EXTRA_VAR),	\
+						      &(ARG)),		\
+		    EXPECTED, EXCEPTIONS);				\
+	EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1);				\
+	if (EXTRA_TEST)							\
+	  check_float (extra1_name, EXTRA_VAR, EXTRA_EXPECTED,		\
+		       (EXCEPTIONS) & TEST_NAN_PAYLOAD);		\
+	EXTRA_OUTPUT_TEST_CLEANUP (1);					\
+	COMMON_TEST_CLEANUP;						\
+      }									\
+  while (0)
+#define RUN_TEST_LOOP_Ffp_b1(FUNC_NAME, ARRAY, ROUNDING_MODE,		\
+			     EXTRA_VAR)					\
+  IF_ROUND_INIT_ ## ROUNDING_MODE					\
+    for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++)	\
+      RUN_TEST_Ffp_b1 ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg,	\
+		       (ARRAY)[i].RM_##ROUNDING_MODE.expected,		\
+		       (ARRAY)[i].RM_##ROUNDING_MODE.exceptions,	\
+		       EXTRA_VAR,					\
+		       (ARRAY)[i].RM_##ROUNDING_MODE.extra_test,	\
+		       (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected);	\
+  ROUND_RESTORE_ ## ROUNDING_MODE
 #define RUN_TEST_c_c(ARG_STR, FUNC_NAME, ARGR, ARGC, EXPR, EXPC,	\
 		     EXCEPTIONS)					\
   do									\
@@ -3557,6 +3620,71 @@ cacosh_test (void)
 }
 
 
+static const struct test_Ffp_b1_data canonicalize_test_data[] =
+  {
+    TEST_Ffp_b1 (canonicalize, plus_infty, 0, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, minus_infty, 0, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, plus_zero, 0, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, minus_zero, 0, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, 1000, 0, 1000, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, max_value, 0, max_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, -max_value, 0, -max_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, min_value, 0, min_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, -min_value, 0, -min_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, min_subnorm_value, 0, min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, -min_subnorm_value, 0, -min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_Ffp_b1 (canonicalize, qnan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value, 0, -qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, snan_value, 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN),
+    TEST_Ffp_b1 (canonicalize, -snan_value, 0, -qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN),
+#if HIGH_ORDER_BIT_IS_SET_FOR_SNAN
+    TEST_Ffp_b1 (canonicalize, snan_value_pl ("0x0"), 0, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN),
+    TEST_Ffp_b1 (canonicalize, -snan_value_pl ("0x0"), 0, -qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN),
+#else
+    TEST_Ffp_b1 (canonicalize, qnan_value_pl ("0x0"), 0, qnan_value_pl ("0x0"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value_pl ("0x0"), 0, -qnan_value_pl ("0x0"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+#endif
+    TEST_Ffp_b1 (canonicalize, qnan_value_pl ("0x1"), 0, qnan_value_pl ("0x1"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value_pl ("0x1"), 0, -qnan_value_pl ("0x1"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, snan_value_pl ("0x1"), 0, qnan_value_pl ("0x1"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, -snan_value_pl ("0x1"), 0, -qnan_value_pl ("0x1"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, qnan_value_pl ("0x2"), 0, qnan_value_pl ("0x2"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value_pl ("0x2"), 0, -qnan_value_pl ("0x2"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, snan_value_pl ("0x2"), 0, qnan_value_pl ("0x2"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, -snan_value_pl ("0x2"), 0, -qnan_value_pl ("0x2"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, qnan_value_pl ("0x3fffff"), 0, qnan_value_pl ("0x3fffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value_pl ("0x3fffff"), 0, -qnan_value_pl ("0x3fffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, snan_value_pl ("0x3fffff"), 0, qnan_value_pl ("0x3fffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, -snan_value_pl ("0x3fffff"), 0, -qnan_value_pl ("0x3fffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+#if PAYLOAD_DIG >= 51
+    TEST_Ffp_b1 (canonicalize, qnan_value_pl ("0x7ffffffffffff"), 0, qnan_value_pl ("0x7ffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value_pl ("0x7ffffffffffff"), 0, -qnan_value_pl ("0x7ffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, snan_value_pl ("0x7ffffffffffff"), 0, qnan_value_pl ("0x7ffffffffffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, -snan_value_pl ("0x7ffffffffffff"), 0, -qnan_value_pl ("0x7ffffffffffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+#endif
+#if PAYLOAD_DIG >= 62
+    TEST_Ffp_b1 (canonicalize, qnan_value_pl ("0x3fffffffffffffff"), 0, qnan_value_pl ("0x3fffffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value_pl ("0x3fffffffffffffff"), 0, -qnan_value_pl ("0x3fffffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, snan_value_pl ("0x3fffffffffffffff"), 0, qnan_value_pl ("0x3fffffffffffffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, -snan_value_pl ("0x3fffffffffffffff"), 0, -qnan_value_pl ("0x3fffffffffffffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+#endif
+#if PAYLOAD_DIG >= 111
+    TEST_Ffp_b1 (canonicalize, qnan_value_pl ("0x7fffffffffffffffffffffffffff"), 0, qnan_value_pl ("0x7fffffffffffffffffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, -qnan_value_pl ("0x7fffffffffffffffffffffffffff"), 0, -qnan_value_pl ("0x7fffffffffffffffffffffffffff"), NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD),
+    TEST_Ffp_b1 (canonicalize, snan_value_pl ("0x7fffffffffffffffffffffffffff"), 0, qnan_value_pl ("0x7fffffffffffffffffffffffffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+    TEST_Ffp_b1 (canonicalize, -snan_value_pl ("0x7fffffffffffffffffffffffffff"), 0, -qnan_value_pl ("0x7fffffffffffffffffffffffffff"), NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_UNCHANGED|TEST_NAN_SIGN|TEST_NAN_PAYLOAD_CANONICALIZE),
+#endif
+  };
+
+static void
+canonicalize_test (void)
+{
+  FLOAT x;
+
+  ALL_RM_TEST (canonicalize, 1, canonicalize_test_data, RUN_TEST_LOOP_Ffp_b1, END, x);
+}
+
+
 static const struct test_c_f_data carg_test_data[] =
   {
     /* carg (x + iy) is specified as atan2 (y, x) */
@@ -13511,6 +13639,9 @@ main (int argc, char **argv)
   totalorder_test ();
   totalordermag_test ();
 
+  /* Canonicalize functions:  */
+  canonicalize_test ();
+
   /* NaN functions:  */
   getpayload_test ();
 
diff --git a/math/s_canonicalize_template.c b/math/s_canonicalize_template.c
new file mode 100644
index 0000000..fa06f5c
--- /dev/null
+++ b/math/s_canonicalize_template.c
@@ -0,0 +1,37 @@
+/* Canonicalize floating-point representation.
+   Copyright (C) 2016 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/>.  */
+
+#include <math.h>
+
+int
+M_DECL_FUNC (__canonicalize) (FLOAT *cx, const FLOAT *x)
+{
+  FLOAT val = *x;
+  /* For all binary formats supported by glibc, iscanonical only fails
+     if the representation is not a valid representation of the type,
+     so the only work to do is for signaling NaNs.  */
+  if (!iscanonical (val))
+    return 1;
+  if (issignaling (val))
+    *cx = val + val;
+  else
+    *cx = val;
+  return 0;
+}
+
+declare_mgen_alias (__canonicalize, canonicalize)
diff --git a/sysdeps/generic/math-tests.h b/sysdeps/generic/math-tests.h
index 974dda4..52f4eae 100644
--- a/sysdeps/generic/math-tests.h
+++ b/sysdeps/generic/math-tests.h
@@ -41,6 +41,14 @@
 # define SNAN_TESTS_TYPE_CAST	1
 #endif
 
+/* Indicate whether operations on signaling NaNs preserve the payload
+   (if possible; it is not possible with a zero payload if the high
+   bit is set for signaling NaNs) when generating a quiet NaN, and
+   this should be tested.  */
+#ifndef SNAN_TESTS_PRESERVE_PAYLOAD
+# define SNAN_TESTS_PRESERVE_PAYLOAD	1
+#endif
+
 /* Indicate whether to run tests involving a given rounding mode for a
    given floating-point type, given that fesetround succeeds for that
    mode.  All are run if fesetround succeeds unless overridden.  */
diff --git a/sysdeps/ieee754/ldbl-128ibm/Makefile b/sysdeps/ieee754/ldbl-128ibm/Makefile
index eb625a7..bdba6cc 100644
--- a/sysdeps/ieee754/ldbl-128ibm/Makefile
+++ b/sysdeps/ieee754/ldbl-128ibm/Makefile
@@ -11,6 +11,6 @@ endif
 
 ifeq ($(subdir),math)
 tests += test-fmodl-ldbl-128ibm test-remainderl-ldbl-128ibm \
-	 test-remquol-ldbl-128ibm test-iscanonical-ldbl-128ibm \
+	 test-remquol-ldbl-128ibm test-canonical-ldbl-128ibm \
 	 test-totalorderl-ldbl-128ibm
 endif
diff --git a/sysdeps/ieee754/ldbl-128ibm/include/bits/iscanonical.h b/sysdeps/ieee754/ldbl-128ibm/include/bits/iscanonical.h
new file mode 100644
index 0000000..bee080b
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm/include/bits/iscanonical.h
@@ -0,0 +1,5 @@
+#include_next <bits/iscanonical.h>
+
+#ifndef _ISOMAC
+libm_hidden_proto (__iscanonicall)
+#endif
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_iscanonicall.c b/sysdeps/ieee754/ldbl-128ibm/s_iscanonicall.c
index 100b401..63ddb82 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_iscanonicall.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_iscanonicall.c
@@ -57,3 +57,4 @@ __iscanonicall (long double x)
   int expdiff = hexp - lexp;
   return expdiff > 53 || (expdiff == 53 && low_p2 && (ix & 1) == 0);
 }
+libm_hidden_def (__iscanonicall)
diff --git a/sysdeps/ieee754/ldbl-128ibm/test-canonical-ldbl-128ibm.c b/sysdeps/ieee754/ldbl-128ibm/test-canonical-ldbl-128ibm.c
new file mode 100644
index 0000000..1fe1bc4
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm/test-canonical-ldbl-128ibm.c
@@ -0,0 +1,230 @@
+/* Test iscanonical and canonicalizel for ldbl-128ibm.
+   Copyright (C) 2016 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/>.  */
+
+#include <float.h>
+#include <math.h>
+#include <math_private.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+struct test
+{
+  double hi, lo;
+  bool canonical;
+};
+
+static const struct test tests[] =
+  {
+    { __builtin_nan (""), 0.0, true },
+    { __builtin_nan (""), DBL_MAX, true },
+    { __builtin_nan (""), __builtin_inf (), true },
+    { __builtin_nan (""), __builtin_nan (""), true },
+    { __builtin_nan (""), __builtin_nans (""), true },
+    { __builtin_nans (""), 0.0, true },
+    { __builtin_nans (""), DBL_MAX, true },
+    { __builtin_nans (""), __builtin_inf (), true },
+    { __builtin_nans (""), __builtin_nan (""), true },
+    { __builtin_nans (""), __builtin_nans (""), true },
+    { __builtin_inf (), 0.0, true },
+    { __builtin_inf (), -0.0, true },
+    { -__builtin_inf (), 0.0, true },
+    { -__builtin_inf (), -0.0, true },
+    { __builtin_inf (), DBL_TRUE_MIN, false },
+    { __builtin_inf (), -DBL_TRUE_MIN, false },
+    { -__builtin_inf (), DBL_TRUE_MIN, false },
+    { -__builtin_inf (), -DBL_TRUE_MIN, false },
+    { __builtin_inf (), DBL_MIN, false },
+    { __builtin_inf (), -DBL_MIN, false },
+    { -__builtin_inf (), DBL_MIN, false },
+    { -__builtin_inf (), -DBL_MIN, false },
+    { __builtin_inf (), __builtin_inf (), false },
+    { __builtin_inf (), -__builtin_inf (), false },
+    { -__builtin_inf (), __builtin_inf (), false },
+    { -__builtin_inf (), -__builtin_inf (), false },
+    { __builtin_inf (), __builtin_nan (""), false },
+    { __builtin_inf (), -__builtin_nan (""), false },
+    { -__builtin_inf (), __builtin_nan (""), false },
+    { -__builtin_inf (), -__builtin_nan (""), false },
+    { 0.0, 0.0, true },
+    { 0.0, -0.0, true },
+    { -0.0, 0.0, true },
+    { -0.0, -0.0, true },
+    { 0.0, DBL_TRUE_MIN, false },
+    { 0.0, -DBL_TRUE_MIN, false },
+    { -0.0, DBL_TRUE_MIN, false },
+    { -0.0, -DBL_TRUE_MIN, false },
+    { 0.0, DBL_MAX, false },
+    { 0.0, -DBL_MAX, false },
+    { -0.0, DBL_MAX, false },
+    { -0.0, -DBL_MAX, false },
+    { 0.0, __builtin_inf (), false },
+    { 0.0, -__builtin_inf (), false },
+    { -0.0, __builtin_inf (), false },
+    { -0.0, -__builtin_inf (), false },
+    { 0.0, __builtin_nan (""), false },
+    { 0.0, -__builtin_nan (""), false },
+    { -0.0, __builtin_nan (""), false },
+    { -0.0, -__builtin_nan (""), false },
+    { 1.0, 0.0, true },
+    { 1.0, -0.0, true },
+    { -1.0, 0.0, true },
+    { -1.0, -0.0, true },
+    { 1.0, DBL_TRUE_MIN, true },
+    { 1.0, -DBL_TRUE_MIN, true },
+    { -1.0, DBL_TRUE_MIN, true },
+    { -1.0, -DBL_TRUE_MIN, true },
+    { 1.0, DBL_MAX, false },
+    { 1.0, -DBL_MAX, false },
+    { -1.0, DBL_MAX, false },
+    { -1.0, -DBL_MAX, false },
+    { 1.0, __builtin_inf (), false },
+    { 1.0, -__builtin_inf (), false },
+    { -1.0, __builtin_inf (), false },
+    { -1.0, -__builtin_inf (), false },
+    { 1.0, __builtin_nan (""), false },
+    { 1.0, -__builtin_nan (""), false },
+    { -1.0, __builtin_nan (""), false },
+    { -1.0, -__builtin_nan (""), false },
+    { 0x1p1023, 0x1.1p969, true },
+    { 0x1p1023, -0x1.1p969, true },
+    { -0x1p1023, 0x1.1p969, true },
+    { -0x1p1023, -0x1.1p969, true },
+    { 0x1p1023, 0x1.1p970, false },
+    { 0x1p1023, -0x1.1p970, false },
+    { -0x1p1023, 0x1.1p970, false },
+    { -0x1p1023, -0x1.1p970, false },
+    { 0x1p1023, 0x1p970, true },
+    { 0x1p1023, -0x1p970, true },
+    { -0x1p1023, 0x1p970, true },
+    { -0x1p1023, -0x1p970, true },
+    { 0x1.0000000000001p1023, 0x1p970, false },
+    { 0x1.0000000000001p1023, -0x1p970, false },
+    { -0x1.0000000000001p1023, 0x1p970, false },
+    { -0x1.0000000000001p1023, -0x1p970, false },
+    { 0x1p-969, 0x1.1p-1023, true },
+    { 0x1p-969, -0x1.1p-1023, true },
+    { -0x1p-969, 0x1.1p-1023, true },
+    { -0x1p-969, -0x1.1p-1023, true },
+    { 0x1p-969, 0x1.1p-1022, false },
+    { 0x1p-969, -0x1.1p-1022, false },
+    { -0x1p-969, 0x1.1p-1022, false },
+    { -0x1p-969, -0x1.1p-1022, false },
+    { 0x1p-969, 0x1p-1022, true },
+    { 0x1p-969, -0x1p-1022, true },
+    { -0x1p-969, 0x1p-1022, true },
+    { -0x1p-969, -0x1p-1022, true },
+    { 0x1.0000000000001p-969, 0x1p-1022, false },
+    { 0x1.0000000000001p-969, -0x1p-1022, false },
+    { -0x1.0000000000001p-969, 0x1p-1022, false },
+    { -0x1.0000000000001p-969, -0x1p-1022, false },
+    { 0x1p-970, 0x1.1p-1024, true },
+    { 0x1p-970, -0x1.1p-1024, true },
+    { -0x1p-970, 0x1.1p-1024, true },
+    { -0x1p-970, -0x1.1p-1024, true },
+    { 0x1p-970, 0x1.1p-1023, false },
+    { 0x1p-970, -0x1.1p-1023, false },
+    { -0x1p-970, 0x1.1p-1023, false },
+    { -0x1p-970, -0x1.1p-1023, false },
+    { 0x1p-970, 0x1p-1023, true },
+    { 0x1p-970, -0x1p-1023, true },
+    { -0x1p-970, 0x1p-1023, true },
+    { -0x1p-970, -0x1p-1023, true },
+    { 0x1.0000000000001p-970, 0x1p-1023, false },
+    { 0x1.0000000000001p-970, -0x1p-1023, false },
+    { -0x1.0000000000001p-970, 0x1p-1023, false },
+    { -0x1.0000000000001p-970, -0x1p-1023, false },
+    { 0x1p-1000, 0x1.1p-1054, true },
+    { 0x1p-1000, -0x1.1p-1054, true },
+    { -0x1p-1000, 0x1.1p-1054, true },
+    { -0x1p-1000, -0x1.1p-1054, true },
+    { 0x1p-1000, 0x1.1p-1053, false },
+    { 0x1p-1000, -0x1.1p-1053, false },
+    { -0x1p-1000, 0x1.1p-1053, false },
+    { -0x1p-1000, -0x1.1p-1053, false },
+    { 0x1p-1000, 0x1p-1053, true },
+    { 0x1p-1000, -0x1p-1053, true },
+    { -0x1p-1000, 0x1p-1053, true },
+    { -0x1p-1000, -0x1p-1053, true },
+    { 0x1.0000000000001p-1000, 0x1p-1053, false },
+    { 0x1.0000000000001p-1000, -0x1p-1053, false },
+    { -0x1.0000000000001p-1000, 0x1p-1053, false },
+    { -0x1.0000000000001p-1000, -0x1p-1053, false },
+    { 0x1p-1021, 0x1p-1074, true },
+    { 0x1p-1021, -0x1p-1074, true },
+    { -0x1p-1021, 0x1p-1074, true },
+    { -0x1p-1021, -0x1p-1074, true },
+    { 0x1.0000000000001p-1021, 0x1p-1074, false },
+    { 0x1.0000000000001p-1021, -0x1p-1074, false },
+    { -0x1.0000000000001p-1021, 0x1p-1074, false },
+    { -0x1.0000000000001p-1021, -0x1p-1074, false },
+    { 0x1p-1022, 0x1p-1074, false },
+    { 0x1p-1022, -0x1p-1074, false },
+    { -0x1p-1022, 0x1p-1074, false },
+    { -0x1p-1022, -0x1p-1074, false },
+  };
+
+static int
+do_test (void)
+{
+  int result = 0;
+
+  for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); i++)
+    {
+      long double ld = ldbl_pack (tests[i].hi, tests[i].lo);
+      bool canonical = iscanonical (ld);
+      if (canonical == tests[i].canonical)
+	{
+	  printf ("PASS: iscanonical test %zu\n", i);
+	  long double ldc = 12345.0L;
+	  bool canonicalize_ret = canonicalizel (&ldc, &ld);
+	  if (canonicalize_ret == !canonical)
+	    {
+	      printf ("PASS: canonicalizel test %zu\n", i);
+	      bool canon_ok;
+	      if (!canonical)
+		canon_ok = ldc == 12345.0L;
+	      else if (isnan (ld))
+		canon_ok = isnan (ldc) && !issignaling (ldc);
+	      else
+		canon_ok = ldc == ld;
+	      if (canon_ok)
+		printf ("PASS: canonicalized value test %zu\n", i);
+	      else
+		{
+		  printf ("FAIL: canonicalized value test %zu\n", i);
+		  result = 1;
+		}
+	    }
+	  else
+	    {
+	      printf ("FAIL: canonicalizel test %zu\n", i);
+	      result = 1;
+	    }
+	}
+      else
+	{
+	  printf ("FAIL: iscanonical test %zu\n", i);
+	  result = 1;
+	}
+    }
+
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/sysdeps/ieee754/ldbl-128ibm/test-iscanonical-ldbl-128ibm.c b/sysdeps/ieee754/ldbl-128ibm/test-iscanonical-ldbl-128ibm.c
deleted file mode 100644
index fc16250..0000000
--- a/sysdeps/ieee754/ldbl-128ibm/test-iscanonical-ldbl-128ibm.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* Test iscanonical for ldbl-128ibm.
-   Copyright (C) 2016 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/>.  */
-
-#include <float.h>
-#include <math.h>
-#include <math_private.h>
-#include <stdbool.h>
-#include <stdio.h>
-
-struct test
-{
-  double hi, lo;
-  bool canonical;
-};
-
-static const struct test tests[] =
-  {
-    { __builtin_nan (""), 0.0, true },
-    { __builtin_nan (""), DBL_MAX, true },
-    { __builtin_nan (""), __builtin_inf (), true },
-    { __builtin_nan (""), __builtin_nan (""), true },
-    { __builtin_nan (""), __builtin_nans (""), true },
-    { __builtin_nans (""), 0.0, true },
-    { __builtin_nans (""), DBL_MAX, true },
-    { __builtin_nans (""), __builtin_inf (), true },
-    { __builtin_nans (""), __builtin_nan (""), true },
-    { __builtin_nans (""), __builtin_nans (""), true },
-    { __builtin_inf (), 0.0, true },
-    { __builtin_inf (), -0.0, true },
-    { -__builtin_inf (), 0.0, true },
-    { -__builtin_inf (), -0.0, true },
-    { __builtin_inf (), DBL_TRUE_MIN, false },
-    { __builtin_inf (), -DBL_TRUE_MIN, false },
-    { -__builtin_inf (), DBL_TRUE_MIN, false },
-    { -__builtin_inf (), -DBL_TRUE_MIN, false },
-    { __builtin_inf (), DBL_MIN, false },
-    { __builtin_inf (), -DBL_MIN, false },
-    { -__builtin_inf (), DBL_MIN, false },
-    { -__builtin_inf (), -DBL_MIN, false },
-    { __builtin_inf (), __builtin_inf (), false },
-    { __builtin_inf (), -__builtin_inf (), false },
-    { -__builtin_inf (), __builtin_inf (), false },
-    { -__builtin_inf (), -__builtin_inf (), false },
-    { __builtin_inf (), __builtin_nan (""), false },
-    { __builtin_inf (), -__builtin_nan (""), false },
-    { -__builtin_inf (), __builtin_nan (""), false },
-    { -__builtin_inf (), -__builtin_nan (""), false },
-    { 0.0, 0.0, true },
-    { 0.0, -0.0, true },
-    { -0.0, 0.0, true },
-    { -0.0, -0.0, true },
-    { 0.0, DBL_TRUE_MIN, false },
-    { 0.0, -DBL_TRUE_MIN, false },
-    { -0.0, DBL_TRUE_MIN, false },
-    { -0.0, -DBL_TRUE_MIN, false },
-    { 0.0, DBL_MAX, false },
-    { 0.0, -DBL_MAX, false },
-    { -0.0, DBL_MAX, false },
-    { -0.0, -DBL_MAX, false },
-    { 0.0, __builtin_inf (), false },
-    { 0.0, -__builtin_inf (), false },
-    { -0.0, __builtin_inf (), false },
-    { -0.0, -__builtin_inf (), false },
-    { 0.0, __builtin_nan (""), false },
-    { 0.0, -__builtin_nan (""), false },
-    { -0.0, __builtin_nan (""), false },
-    { -0.0, -__builtin_nan (""), false },
-    { 1.0, 0.0, true },
-    { 1.0, -0.0, true },
-    { -1.0, 0.0, true },
-    { -1.0, -0.0, true },
-    { 1.0, DBL_TRUE_MIN, true },
-    { 1.0, -DBL_TRUE_MIN, true },
-    { -1.0, DBL_TRUE_MIN, true },
-    { -1.0, -DBL_TRUE_MIN, true },
-    { 1.0, DBL_MAX, false },
-    { 1.0, -DBL_MAX, false },
-    { -1.0, DBL_MAX, false },
-    { -1.0, -DBL_MAX, false },
-    { 1.0, __builtin_inf (), false },
-    { 1.0, -__builtin_inf (), false },
-    { -1.0, __builtin_inf (), false },
-    { -1.0, -__builtin_inf (), false },
-    { 1.0, __builtin_nan (""), false },
-    { 1.0, -__builtin_nan (""), false },
-    { -1.0, __builtin_nan (""), false },
-    { -1.0, -__builtin_nan (""), false },
-    { 0x1p1023, 0x1.1p969, true },
-    { 0x1p1023, -0x1.1p969, true },
-    { -0x1p1023, 0x1.1p969, true },
-    { -0x1p1023, -0x1.1p969, true },
-    { 0x1p1023, 0x1.1p970, false },
-    { 0x1p1023, -0x1.1p970, false },
-    { -0x1p1023, 0x1.1p970, false },
-    { -0x1p1023, -0x1.1p970, false },
-    { 0x1p1023, 0x1p970, true },
-    { 0x1p1023, -0x1p970, true },
-    { -0x1p1023, 0x1p970, true },
-    { -0x1p1023, -0x1p970, true },
-    { 0x1.0000000000001p1023, 0x1p970, false },
-    { 0x1.0000000000001p1023, -0x1p970, false },
-    { -0x1.0000000000001p1023, 0x1p970, false },
-    { -0x1.0000000000001p1023, -0x1p970, false },
-    { 0x1p-969, 0x1.1p-1023, true },
-    { 0x1p-969, -0x1.1p-1023, true },
-    { -0x1p-969, 0x1.1p-1023, true },
-    { -0x1p-969, -0x1.1p-1023, true },
-    { 0x1p-969, 0x1.1p-1022, false },
-    { 0x1p-969, -0x1.1p-1022, false },
-    { -0x1p-969, 0x1.1p-1022, false },
-    { -0x1p-969, -0x1.1p-1022, false },
-    { 0x1p-969, 0x1p-1022, true },
-    { 0x1p-969, -0x1p-1022, true },
-    { -0x1p-969, 0x1p-1022, true },
-    { -0x1p-969, -0x1p-1022, true },
-    { 0x1.0000000000001p-969, 0x1p-1022, false },
-    { 0x1.0000000000001p-969, -0x1p-1022, false },
-    { -0x1.0000000000001p-969, 0x1p-1022, false },
-    { -0x1.0000000000001p-969, -0x1p-1022, false },
-    { 0x1p-970, 0x1.1p-1024, true },
-    { 0x1p-970, -0x1.1p-1024, true },
-    { -0x1p-970, 0x1.1p-1024, true },
-    { -0x1p-970, -0x1.1p-1024, true },
-    { 0x1p-970, 0x1.1p-1023, false },
-    { 0x1p-970, -0x1.1p-1023, false },
-    { -0x1p-970, 0x1.1p-1023, false },
-    { -0x1p-970, -0x1.1p-1023, false },
-    { 0x1p-970, 0x1p-1023, true },
-    { 0x1p-970, -0x1p-1023, true },
-    { -0x1p-970, 0x1p-1023, true },
-    { -0x1p-970, -0x1p-1023, true },
-    { 0x1.0000000000001p-970, 0x1p-1023, false },
-    { 0x1.0000000000001p-970, -0x1p-1023, false },
-    { -0x1.0000000000001p-970, 0x1p-1023, false },
-    { -0x1.0000000000001p-970, -0x1p-1023, false },
-    { 0x1p-1000, 0x1.1p-1054, true },
-    { 0x1p-1000, -0x1.1p-1054, true },
-    { -0x1p-1000, 0x1.1p-1054, true },
-    { -0x1p-1000, -0x1.1p-1054, true },
-    { 0x1p-1000, 0x1.1p-1053, false },
-    { 0x1p-1000, -0x1.1p-1053, false },
-    { -0x1p-1000, 0x1.1p-1053, false },
-    { -0x1p-1000, -0x1.1p-1053, false },
-    { 0x1p-1000, 0x1p-1053, true },
-    { 0x1p-1000, -0x1p-1053, true },
-    { -0x1p-1000, 0x1p-1053, true },
-    { -0x1p-1000, -0x1p-1053, true },
-    { 0x1.0000000000001p-1000, 0x1p-1053, false },
-    { 0x1.0000000000001p-1000, -0x1p-1053, false },
-    { -0x1.0000000000001p-1000, 0x1p-1053, false },
-    { -0x1.0000000000001p-1000, -0x1p-1053, false },
-    { 0x1p-1021, 0x1p-1074, true },
-    { 0x1p-1021, -0x1p-1074, true },
-    { -0x1p-1021, 0x1p-1074, true },
-    { -0x1p-1021, -0x1p-1074, true },
-    { 0x1.0000000000001p-1021, 0x1p-1074, false },
-    { 0x1.0000000000001p-1021, -0x1p-1074, false },
-    { -0x1.0000000000001p-1021, 0x1p-1074, false },
-    { -0x1.0000000000001p-1021, -0x1p-1074, false },
-    { 0x1p-1022, 0x1p-1074, false },
-    { 0x1p-1022, -0x1p-1074, false },
-    { -0x1p-1022, 0x1p-1074, false },
-    { -0x1p-1022, -0x1p-1074, false },
-  };
-
-static int
-do_test (void)
-{
-  int result = 0;
-
-  for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); i++)
-    {
-      long double ld = ldbl_pack (tests[i].hi, tests[i].lo);
-      bool canonical = iscanonical (ld);
-      if (canonical == tests[i].canonical)
-	printf ("PASS: test %zu\n", i);
-      else
-	{
-	  printf ("FAIL: test %zu\n", i);
-	  result = 1;
-	}
-    }
-
-  return result;
-}
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
diff --git a/sysdeps/ieee754/ldbl-96/Makefile b/sysdeps/ieee754/ldbl-96/Makefile
index 931976d..dcbfbba 100644
--- a/sysdeps/ieee754/ldbl-96/Makefile
+++ b/sysdeps/ieee754/ldbl-96/Makefile
@@ -17,5 +17,5 @@
 # <http://www.gnu.org/licenses/>.
 
 ifeq ($(subdir),math)
-tests += test-iscanonical-ldbl-96 test-totalorderl-ldbl-96
+tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96
 endif
diff --git a/sysdeps/ieee754/ldbl-96/include/bits/iscanonical.h b/sysdeps/ieee754/ldbl-96/include/bits/iscanonical.h
new file mode 100644
index 0000000..bee080b
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-96/include/bits/iscanonical.h
@@ -0,0 +1,5 @@
+#include_next <bits/iscanonical.h>
+
+#ifndef _ISOMAC
+libm_hidden_proto (__iscanonicall)
+#endif
diff --git a/sysdeps/ieee754/ldbl-96/s_iscanonicall.c b/sysdeps/ieee754/ldbl-96/s_iscanonicall.c
index f820030..91ce80d 100644
--- a/sysdeps/ieee754/ldbl-96/s_iscanonicall.c
+++ b/sysdeps/ieee754/ldbl-96/s_iscanonicall.c
@@ -41,3 +41,4 @@ __iscanonicall (long double x)
        the high bit to be set.  */
     return ix == 0 || ix == 0x7fff || mant_high;
 }
+libm_hidden_def (__iscanonicall)
diff --git a/sysdeps/ieee754/ldbl-96/test-canonical-ldbl-96.c b/sysdeps/ieee754/ldbl-96/test-canonical-ldbl-96.c
new file mode 100644
index 0000000..ce6dc5b
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-96/test-canonical-ldbl-96.c
@@ -0,0 +1,141 @@
+/* Test iscanonical and canonicalizel for ldbl-96.
+   Copyright (C) 2016 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/>.  */
+
+#include <float.h>
+#include <math.h>
+#include <math_private.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+
+struct test
+{
+  bool sign;
+  uint16_t exponent;
+  bool high;
+  uint64_t mantissa;
+  bool canonical;
+};
+
+#define M68K_VARIANT (LDBL_MIN_EXP == -16382)
+
+static const struct test tests[] =
+  {
+    { false, 0, true, 0, M68K_VARIANT },
+    { true, 0, true, 0, M68K_VARIANT },
+    { false, 0, true, 1, M68K_VARIANT },
+    { true, 0, true, 1, M68K_VARIANT },
+    { false, 0, true, 0x100000000ULL, M68K_VARIANT },
+    { true, 0, true, 0x100000000ULL, M68K_VARIANT },
+    { false, 0, false, 0, true },
+    { true, 0, false, 0, true },
+    { false, 0, false, 1, true },
+    { true, 0, false, 1, true },
+    { false, 0, false, 0x100000000ULL, true },
+    { true, 0, false, 0x100000000ULL, true },
+    { false, 1, true, 0, true },
+    { true, 1, true, 0, true },
+    { false, 1, true, 1, true },
+    { true, 1, true, 1, true },
+    { false, 1, true, 0x100000000ULL, true },
+    { true, 1, true, 0x100000000ULL, true },
+    { false, 1, false, 0, false },
+    { true, 1, false, 0, false },
+    { false, 1, false, 1, false },
+    { true, 1, false, 1, false },
+    { false, 1, false, 0x100000000ULL, false },
+    { true, 1, false, 0x100000000ULL, false },
+    { false, 0x7ffe, true, 0, true },
+    { true, 0x7ffe, true, 0, true },
+    { false, 0x7ffe, true, 1, true },
+    { true, 0x7ffe, true, 1, true },
+    { false, 0x7ffe, true, 0x100000000ULL, true },
+    { true, 0x7ffe, true, 0x100000000ULL, true },
+    { false, 0x7ffe, false, 0, false },
+    { true, 0x7ffe, false, 0, false },
+    { false, 0x7ffe, false, 1, false },
+    { true, 0x7ffe, false, 1, false },
+    { false, 0x7ffe, false, 0x100000000ULL, false },
+    { true, 0x7ffe, false, 0x100000000ULL, false },
+    { false, 0x7fff, true, 0, true },
+    { true, 0x7fff, true, 0, true },
+    { false, 0x7fff, true, 1, true },
+    { true, 0x7fff, true, 1, true },
+    { false, 0x7fff, true, 0x100000000ULL, true },
+    { true, 0x7fff, true, 0x100000000ULL, true },
+    { false, 0x7fff, false, 0, M68K_VARIANT },
+    { true, 0x7fff, false, 0, M68K_VARIANT },
+    { false, 0x7fff, false, 1, M68K_VARIANT },
+    { true, 0x7fff, false, 1, M68K_VARIANT },
+    { false, 0x7fff, false, 0x100000000ULL, M68K_VARIANT },
+    { true, 0x7fff, false, 0x100000000ULL, M68K_VARIANT },
+  };
+
+static int
+do_test (void)
+{
+  int result = 0;
+
+  for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); i++)
+    {
+      long double ld;
+      SET_LDOUBLE_WORDS (ld, tests[i].exponent | (tests[i].sign << 15),
+			 (tests[i].mantissa >> 32) | (tests[i].high << 31),
+			 tests[i].mantissa & 0xffffffffULL);
+      bool canonical = iscanonical (ld);
+      if (canonical == tests[i].canonical)
+	{
+	  printf ("PASS: iscanonical test %zu\n", i);
+	  long double ldc = 12345.0L;
+	  bool canonicalize_ret = canonicalizel (&ldc, &ld);
+	  if (canonicalize_ret == !canonical)
+	    {
+	      printf ("PASS: canonicalizel test %zu\n", i);
+	      bool canon_ok;
+	      if (!canonical)
+		canon_ok = ldc == 12345.0L;
+	      else if (isnan (ld))
+		canon_ok = isnan (ldc) && !issignaling (ldc);
+	      else
+		canon_ok = ldc == ld;
+	      if (canon_ok)
+		printf ("PASS: canonicalized value test %zu\n", i);
+	      else
+		{
+		  printf ("FAIL: canonicalized value test %zu\n", i);
+		  result = 1;
+		}
+	    }
+	  else
+	    {
+	      printf ("FAIL: canonicalizel test %zu\n", i);
+	      result = 1;
+	    }
+	}
+      else
+	{
+	  printf ("FAIL: iscanonical test %zu\n", i);
+	  result = 1;
+	}
+    }
+
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/sysdeps/ieee754/ldbl-96/test-iscanonical-ldbl-96.c b/sysdeps/ieee754/ldbl-96/test-iscanonical-ldbl-96.c
deleted file mode 100644
index 6827aa8..0000000
--- a/sysdeps/ieee754/ldbl-96/test-iscanonical-ldbl-96.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Test iscanonical for ldbl-96.
-   Copyright (C) 2016 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/>.  */
-
-#include <float.h>
-#include <math.h>
-#include <math_private.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-
-struct test
-{
-  bool sign;
-  uint16_t exponent;
-  bool high;
-  uint64_t mantissa;
-  bool canonical;
-};
-
-#define M68K_VARIANT (LDBL_MIN_EXP == -16382)
-
-static const struct test tests[] =
-  {
-    { false, 0, true, 0, M68K_VARIANT },
-    { true, 0, true, 0, M68K_VARIANT },
-    { false, 0, true, 1, M68K_VARIANT },
-    { true, 0, true, 1, M68K_VARIANT },
-    { false, 0, true, 0x100000000ULL, M68K_VARIANT },
-    { true, 0, true, 0x100000000ULL, M68K_VARIANT },
-    { false, 0, false, 0, true },
-    { true, 0, false, 0, true },
-    { false, 0, false, 1, true },
-    { true, 0, false, 1, true },
-    { false, 0, false, 0x100000000ULL, true },
-    { true, 0, false, 0x100000000ULL, true },
-    { false, 1, true, 0, true },
-    { true, 1, true, 0, true },
-    { false, 1, true, 1, true },
-    { true, 1, true, 1, true },
-    { false, 1, true, 0x100000000ULL, true },
-    { true, 1, true, 0x100000000ULL, true },
-    { false, 1, false, 0, false },
-    { true, 1, false, 0, false },
-    { false, 1, false, 1, false },
-    { true, 1, false, 1, false },
-    { false, 1, false, 0x100000000ULL, false },
-    { true, 1, false, 0x100000000ULL, false },
-    { false, 0x7ffe, true, 0, true },
-    { true, 0x7ffe, true, 0, true },
-    { false, 0x7ffe, true, 1, true },
-    { true, 0x7ffe, true, 1, true },
-    { false, 0x7ffe, true, 0x100000000ULL, true },
-    { true, 0x7ffe, true, 0x100000000ULL, true },
-    { false, 0x7ffe, false, 0, false },
-    { true, 0x7ffe, false, 0, false },
-    { false, 0x7ffe, false, 1, false },
-    { true, 0x7ffe, false, 1, false },
-    { false, 0x7ffe, false, 0x100000000ULL, false },
-    { true, 0x7ffe, false, 0x100000000ULL, false },
-    { false, 0x7fff, true, 0, true },
-    { true, 0x7fff, true, 0, true },
-    { false, 0x7fff, true, 1, true },
-    { true, 0x7fff, true, 1, true },
-    { false, 0x7fff, true, 0x100000000ULL, true },
-    { true, 0x7fff, true, 0x100000000ULL, true },
-    { false, 0x7fff, false, 0, M68K_VARIANT },
-    { true, 0x7fff, false, 0, M68K_VARIANT },
-    { false, 0x7fff, false, 1, M68K_VARIANT },
-    { true, 0x7fff, false, 1, M68K_VARIANT },
-    { false, 0x7fff, false, 0x100000000ULL, M68K_VARIANT },
-    { true, 0x7fff, false, 0x100000000ULL, M68K_VARIANT },
-  };
-
-static int
-do_test (void)
-{
-  int result = 0;
-
-  for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); i++)
-    {
-      long double ld;
-      SET_LDOUBLE_WORDS (ld, tests[i].exponent | (tests[i].sign << 15),
-			 (tests[i].mantissa >> 32) | (tests[i].high << 31),
-			 tests[i].mantissa & 0xffffffffULL);
-      bool canonical = iscanonical (ld);
-      if (canonical == tests[i].canonical)
-	printf ("PASS: test %zu\n", i);
-      else
-	{
-	  printf ("FAIL: test %zu\n", i);
-	  result = 1;
-	}
-    }
-
-  return result;
-}
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
diff --git a/sysdeps/ieee754/ldbl-opt/Makefile b/sysdeps/ieee754/ldbl-opt/Makefile
index e97abdc..745fa4c 100644
--- a/sysdeps/ieee754/ldbl-opt/Makefile
+++ b/sysdeps/ieee754/ldbl-opt/Makefile
@@ -42,7 +42,8 @@ libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
 		 isoc99_vscanf isoc99_vfscanf isoc99_vsscanf \
 		 isoc99_wscanf isoc99_fwscanf isoc99_swscanf \
 		 isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf \
-		 nextup nextdown totalorder totalordermag getpayload
+		 nextup nextdown totalorder totalordermag getpayload \
+		 canonicalize
 libnldbl-routines = $(libnldbl-calls:%=nldbl-%)
 libnldbl-inhibit-o = $(object-suffixes)
 libnldbl-static-only-routines = $(libnldbl-routines)
@@ -58,6 +59,7 @@ CFLAGS-nldbl-atanh.c = -fno-builtin-atanhl
 CFLAGS-nldbl-cabs.c = -fno-builtin-cabsl
 CFLAGS-nldbl-cacos.c = -fno-builtin-cacosl
 CFLAGS-nldbl-cacosh.c = -fno-builtin-cacoshl
+CFLAGS-nldbl-canonicalize.c = -fno-builtin-canonicalizel
 CFLAGS-nldbl-carg.c = -fno-builtin-cargl
 CFLAGS-nldbl-casin.c = -fno-builtin-casinl
 CFLAGS-nldbl-casinh.c = -fno-builtin-casinhl
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-canonicalize.c b/sysdeps/ieee754/ldbl-opt/nldbl-canonicalize.c
new file mode 100644
index 0000000..3b33d5c
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/nldbl-canonicalize.c
@@ -0,0 +1,26 @@
+/* Compatibility routine for IEEE double as long double for canonicalize.
+   Copyright (C) 2016 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/>.  */
+
+#include "nldbl-compat.h"
+
+int
+attribute_hidden
+canonicalizel (double *cx, double *x)
+{
+  return canonicalize (cx, x);
+}
diff --git a/sysdeps/ieee754/ldbl-opt/s_canonicalizel.c b/sysdeps/ieee754/ldbl-opt/s_canonicalizel.c
new file mode 100644
index 0000000..d5d67df
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/s_canonicalizel.c
@@ -0,0 +1,5 @@
+/* canonicalizel is not subject to complex aliasing rules.  It was
+   added in glibc 2.25.  */
+#define declare_mgen_alias(from, to) weak_alias (M_SUF (from), M_SUF (to))
+#include <math-type-macros-ldouble.h>
+#include <s_canonicalize_template.c>
diff --git a/sysdeps/mips/math-tests.h b/sysdeps/mips/math-tests.h
index f41c161..fb08bca 100644
--- a/sysdeps/mips/math-tests.h
+++ b/sysdeps/mips/math-tests.h
@@ -35,4 +35,10 @@
 # define EXCEPTION_TESTS_long_double	0
 #endif
 
+/* NaN payload preservation when converting a signaling NaN to quiet
+   is only required in NAN2008 mode.  */
+#if defined __mips_hard_float && !defined __mips_nan2008
+# define SNAN_TESTS_PRESERVE_PAYLOAD	0
+#endif
+
 #include_next <math-tests.h>
diff --git a/sysdeps/nacl/libm.abilist b/sysdeps/nacl/libm.abilist
index b721bfb..b0fc19f 100644
--- a/sysdeps/nacl/libm.abilist
+++ b/sysdeps/nacl/libm.abilist
@@ -382,6 +382,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libm.abilist b/sysdeps/unix/sysv/linux/aarch64/libm.abilist
index dbd620e..9d5936c 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libm.abilist
@@ -414,6 +414,9 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/alpha/libm.abilist b/sysdeps/unix/sysv/linux/alpha/libm.abilist
index 3af146a..ce5be3c 100644
--- a/sysdeps/unix/sysv/linux/alpha/libm.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libm.abilist
@@ -424,6 +424,9 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/arm/libm.abilist b/sysdeps/unix/sysv/linux/arm/libm.abilist
index 502b512..675dfa5 100644
--- a/sysdeps/unix/sysv/linux/arm/libm.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libm.abilist
@@ -71,6 +71,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/hppa/libm.abilist b/sysdeps/unix/sysv/linux/hppa/libm.abilist
index 232ef8e..75b71ad 100644
--- a/sysdeps/unix/sysv/linux/hppa/libm.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libm.abilist
@@ -383,6 +383,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/i386/libm.abilist b/sysdeps/unix/sysv/linux/i386/libm.abilist
index b6151a9..5db3def 100644
--- a/sysdeps/unix/sysv/linux/i386/libm.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libm.abilist
@@ -427,6 +427,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/ia64/libm.abilist b/sysdeps/unix/sysv/linux/ia64/libm.abilist
index 941c4bf..a80c93a 100644
--- a/sysdeps/unix/sysv/linux/ia64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libm.abilist
@@ -356,6 +356,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
index 502b512..675dfa5 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
@@ -71,6 +71,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist
index 1080dc6..c795dbd 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist
@@ -425,6 +425,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libm.abilist b/sysdeps/unix/sysv/linux/microblaze/libm.abilist
index f86e20c..cdc8f19 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libm.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libm.abilist
@@ -382,6 +382,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
index 7965bf2..a610b03 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
@@ -384,6 +384,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
index 0711e03..dfd888c 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
@@ -416,6 +416,9 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/nios2/libm.abilist b/sysdeps/unix/sysv/linux/nios2/libm.abilist
index b4b8164..a6c505d 100644
--- a/sysdeps/unix/sysv/linux/nios2/libm.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libm.abilist
@@ -382,6 +382,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
index d5253c1..9a5f983 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
@@ -427,6 +427,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
index 274eede..24f0127 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
@@ -426,6 +426,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist
index 1af5a2f..00c7d22 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist
@@ -421,6 +421,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist
index 767905c..bfbaa36 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist
@@ -102,6 +102,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
index 342a27b..6e52936 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
@@ -414,6 +414,9 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
index 58b6e50..a01c588 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
@@ -412,6 +412,9 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/sh/libm.abilist b/sysdeps/unix/sysv/linux/sh/libm.abilist
index ab55099..9649784 100644
--- a/sysdeps/unix/sysv/linux/sh/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libm.abilist
@@ -383,6 +383,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
index 76c6e8e..ba10933 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
@@ -417,6 +417,9 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
index 4e54a03..82245ed 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
@@ -415,6 +415,9 @@ GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist
index e9a7426..1d4d6f9 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist
@@ -383,6 +383,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist
index e9a7426..1d4d6f9 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist
@@ -383,6 +383,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist
index e9a7426..1d4d6f9 100644
--- a/sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist
@@ -383,6 +383,9 @@ GLIBC_2.24 nextupl F
 GLIBC_2.25 GLIBC_2.25 A
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
index ab57b58..b0bbada 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
@@ -416,6 +416,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
index 8aaa2a4..87f0852 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
@@ -415,6 +415,9 @@ GLIBC_2.25 __iscanonicall F
 GLIBC_2.25 __iseqsig F
 GLIBC_2.25 __iseqsigf F
 GLIBC_2.25 __iseqsigl F
+GLIBC_2.25 canonicalize F
+GLIBC_2.25 canonicalizef F
+GLIBC_2.25 canonicalizel F
 GLIBC_2.25 fegetmode F
 GLIBC_2.25 fesetexcept F
 GLIBC_2.25 fesetmode F
