about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog94
-rw-r--r--NEWS2
-rw-r--r--manual/arith.texi30
-rwxr-xr-xmanual/libm-err-tab.pl8
-rw-r--r--math/Makefile2
-rw-r--r--math/Versions1
-rw-r--r--math/bits/mathcalls.h3
-rw-r--r--math/libm-test.inc155
-rw-r--r--math/s_canonicalize_template.c37
-rw-r--r--sysdeps/generic/math-tests.h8
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/Makefile2
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/include/bits/iscanonical.h5
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_iscanonicall.c1
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/test-canonical-ldbl-128ibm.c (renamed from sysdeps/ieee754/ldbl-128ibm/test-iscanonical-ldbl-128ibm.c)33
-rw-r--r--sysdeps/ieee754/ldbl-96/Makefile2
-rw-r--r--sysdeps/ieee754/ldbl-96/include/bits/iscanonical.h5
-rw-r--r--sysdeps/ieee754/ldbl-96/s_iscanonicall.c1
-rw-r--r--sysdeps/ieee754/ldbl-96/test-canonical-ldbl-96.c (renamed from sysdeps/ieee754/ldbl-96/test-iscanonical-ldbl-96.c)33
-rw-r--r--sysdeps/ieee754/ldbl-opt/Makefile4
-rw-r--r--sysdeps/ieee754/ldbl-opt/nldbl-canonicalize.c26
-rw-r--r--sysdeps/ieee754/ldbl-opt/s_canonicalizel.c5
-rw-r--r--sysdeps/mips/math-tests.h6
-rw-r--r--sysdeps/nacl/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/alpha/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/arm/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/hppa/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/i386/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/ia64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/nios2/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/sh/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/64/libm.abilist3
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist3
49 files changed, 518 insertions, 26 deletions
diff --git a/ChangeLog b/ChangeLog
index 35813818ca..7dbfbc8d65 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,99 @@
 2016-10-26  Joseph Myers  <joseph@codesourcery.com>
 
+	* math/bits/mathcalls.h [__GLIBC_USE (IEC_60559_BFP_EXT)]
+	(canonicalize): New declaration.
+	* math/Versions (canonicalize): New libm symbol at version
+	GLIBC_2.25.
+	(canonicalizef): Likewise.
+	(canonicalizel): Likewise.
+	* math/Makefile (gen-libm-calls): Add s_canonicalizeF.
+	* math/s_canonicalize_template.c: New file.
+	* math/libm-test.inc: Update comment on functions tested and
+	testing of NaN payloads.
+	(TEST_NAN_PAYLOAD): New macro.
+	(NO_TEST_INLINE): Update value.
+	(XFAIL_TEST): Likewise.
+	(ERRNO_UNCHANGED): Likewise.
+	(ERRNO_EDOM): Likewise.
+	(ERRNO_ERANGE): Likewise.
+	(IGNORE_RESULT): Likewise.
+	(NON_FINITE): Likewise.
+	(TEST_SNAN): Likewise.
+	(NO_TEST_MATHVEC): Likewise.
+	(TEST_NAN_PAYLOAD_CANONICALIZE): New macro.
+	(check_float_internal): Check NaN payloads if TEST_NAN_PAYLOAD.
+	(struct test_Ffp_b1_data): New type.
+	(RUN_TEST_Ffp_b1): New macro.
+	(RUN_TEST_LOOP_Ffp_b1): Likewise.
+	(canonicalize_test_data): New array.
+	(canonicalize_test): New function.
+	(main): Call canonicalize_test.
+	* manual/arith.texi (FP Bit Twiddling): Document canonicalize,
+	canonicalizef and canonicalizel.
+	* manual/libm-err-tab.pl: Update comment on interfaces without
+	ulps tabulated.
+	* sysdeps/ieee754/ldbl-opt/nldbl-canonicalize.c: New file.
+	* sysdeps/ieee754/ldbl-opt/s_canonicalizel.c: Likewise.
+	* sysdeps/ieee754/ldbl-opt/Makefile (libnldbl-calls): Add
+	canonicalize.
+	(CFLAGS-nldbl-canonicalize.c): New variable.
+	* sysdeps/ieee754/ldbl-128ibm/test-iscanonical-ldbl-128ibm.c: Move
+	to ...
+	* sysdeps/ieee754/ldbl-128ibm/test-canonical-ldbl-128ibm.c:
+	... here.
+	(do_test): Also test canonicalizel.
+	* sysdeps/ieee754/ldbl-128ibm/Makefile (tests): Change
+	test-iscanonical-ldbl-128ibm to test-canonical-ldbl-128ibm.
+	* sysdeps/ieee754/ldbl-128ibm/include/bits/iscanonical.h: New
+	file.
+	* sysdeps/ieee754/ldbl-128ibm/s_iscanonicall.c (__iscanonicall):
+	Use libm_hidden_def.
+	* sysdeps/ieee754/ldbl-96/test-iscanonical-ldbl-96.c: Move to ...
+	* sysdeps/ieee754/ldbl-96/test-canonical-ldbl-96.c: ... here.
+	(do_test): Also test canonicalizel.
+	* sysdeps/ieee754/ldbl-96/Makefile (tests): Change
+	test-iscanonical-ldbl-96 to test-canonical-ldbl-96.
+	* sysdeps/ieee754/ldbl-96/include/bits/iscanonical.h: New file.
+	* sysdeps/ieee754/ldbl-96/s_iscanonicall.c (__iscanonicall): Use
+	libm_hidden_def.
+	* sysdeps/generic/math-tests.h (SNAN_TESTS_PRESERVE_PAYLOAD): New
+	macro.
+	* sysdeps/mips/math-tests.h [__mips_hard_float && !__mips_nan2008]
+	(SNAN_TESTS_PRESERVE_PAYLOAD): Likewise.
+	* sysdeps/nacl/libm.abilist: Update.
+	* sysdeps/unix/sysv/linux/aarch64/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/alpha/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/arm/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/hppa/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/i386/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/ia64/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/microblaze/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips32/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/mips/mips64/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/nios2/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/sh/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist:
+	Likewise.
+	* sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/64/libm.abilist: Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist: Likewise.
+
 	* sysdeps/ieee754/ldbl-opt/nldbl-getpayload.c: New file.
 	* sysdeps/ieee754/ldbl-opt/Makefile (libnldbl-calls): Add
 	getpayload.
diff --git a/NEWS b/NEWS
index ea1a0e0371..2da72cdf7a 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 eaaf2b7127..a5c04e475f 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 59c53720b3..18b8ca988f 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 7cecba5357..f400d7b741 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 a2e0d900ad..0cd594b378 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 c5853a325f..2fd1d289da 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 89e0e59638..710633842c 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 0000000000..fa06f5c083
--- /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 974dda403a..52f4eaee4e 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 eb625a7234..bdba6cc6b5 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 0000000000..bee080bd29
--- /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 100b4014e1..63ddb82402 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-iscanonical-ldbl-128ibm.c b/sysdeps/ieee754/ldbl-128ibm/test-canonical-ldbl-128ibm.c
index fc16250f5c..1fe1bc4555 100644
--- a/sysdeps/ieee754/ldbl-128ibm/test-iscanonical-ldbl-128ibm.c
+++ b/sysdeps/ieee754/ldbl-128ibm/test-canonical-ldbl-128ibm.c
@@ -1,4 +1,4 @@
-/* Test iscanonical for ldbl-128ibm.
+/* Test iscanonical and canonicalizel for ldbl-128ibm.
    Copyright (C) 2016 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -188,10 +188,37 @@ do_test (void)
       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);
+	{
+	  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: test %zu\n", i);
+	  printf ("FAIL: iscanonical test %zu\n", i);
 	  result = 1;
 	}
     }
diff --git a/sysdeps/ieee754/ldbl-96/Makefile b/sysdeps/ieee754/ldbl-96/Makefile
index 931976d7b1..dcbfbbac25 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 0000000000..bee080bd29
--- /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 f820030dc0..91ce80d4f1 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-iscanonical-ldbl-96.c b/sysdeps/ieee754/ldbl-96/test-canonical-ldbl-96.c
index 6827aa8108..ce6dc5b3fa 100644
--- a/sysdeps/ieee754/ldbl-96/test-iscanonical-ldbl-96.c
+++ b/sysdeps/ieee754/ldbl-96/test-canonical-ldbl-96.c
@@ -1,4 +1,4 @@
-/* Test iscanonical for ldbl-96.
+/* Test iscanonical and canonicalizel for ldbl-96.
    Copyright (C) 2016 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -99,10 +99,37 @@ do_test (void)
 			 tests[i].mantissa & 0xffffffffULL);
       bool canonical = iscanonical (ld);
       if (canonical == tests[i].canonical)
-	printf ("PASS: test %zu\n", i);
+	{
+	  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: test %zu\n", i);
+	  printf ("FAIL: iscanonical test %zu\n", i);
 	  result = 1;
 	}
     }
diff --git a/sysdeps/ieee754/ldbl-opt/Makefile b/sysdeps/ieee754/ldbl-opt/Makefile
index e97abdc44d..745fa4c8cf 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 0000000000..3b33d5c57e
--- /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 0000000000..d5d67dfe0c
--- /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 f41c1616b0..fb08bca418 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 b721bfb379..b0fc19f9f7 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 dbd620e474..9d5936c5c6 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 3af146a00d..ce5be3c567 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 502b5128c8..675dfa5b86 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 232ef8ea3e..75b71ad8f7 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 b6151a9680..5db3def6fd 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 941c4bf49a..a80c93a00f 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 502b5128c8..675dfa5b86 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 1080dc6cda..c795dbdc88 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 f86e20c775..cdc8f19971 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 7965bf20dc..a610b03eba 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 0711e03a8b..dfd888cf70 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 b4b81647ac..a6c505d19a 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 d5253c1244..9a5f983c3c 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 274eede940..24f0127055 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 1af5a2fa74..00c7d22dfc 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 767905c801..bfbaa36634 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 342a27b7c8..6e52936a88 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 58b6e50d85..a01c58857b 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 ab550995a5..96497844bb 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 76c6e8e818..ba10933919 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 4e54a03eff..82245edfba 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 e9a7426ac6..1d4d6f98c6 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 e9a7426ac6..1d4d6f98c6 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 e9a7426ac6..1d4d6f98c6 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 ab57b5867d..b0bbadac09 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 8aaa2a4ab8..87f085202f 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