diff mbox series

Add narrowing square root functions [committed]

Message ID alpine.DEB.2.22.394.2109102058250.3000749@digraph.polyomino.org.uk
State New
Headers show
Series Add narrowing square root functions [committed] | expand

Commit Message

Joseph Myers Sept. 10, 2021, 8:58 p.m. UTC
This patch adds the narrowing square root functions from TS 18661-1 /
TS 18661-3 / C2X to glibc's libm: fsqrt, fsqrtl, dsqrtl, f32sqrtf64,
f32sqrtf32x, f32xsqrtf64 for all configurations; f32sqrtf64x,
f32sqrtf128, f64sqrtf64x, f64sqrtf128, f32xsqrtf64x, f32xsqrtf128,
f64xsqrtf128 for configurations with _Float64x and _Float128;
__f32sqrtieee128 and __f64sqrtieee128 aliases in the powerpc64le case
(for calls to fsqrtl and dsqrtl when long double is IEEE binary128).
Corresponding tgmath.h macro support is also added.

The changes are mostly similar to those for the other narrowing
functions previously added, so the description of those generally
applies to this patch as well.  However, the not-actually-narrowing
cases (where the two types involved in the function have the same
floating-point format) are aliased to sqrt, sqrtl or sqrtf128 rather
than needing a separately built not-actually-narrowing function such
as was needed for add / sub / mul / div.  Thus, there is no
__nldbl_dsqrtl name for ldbl-opt because no such name was needed
(whereas the other functions needed such a name since the only other
name for that entry point was e.g. f32xaddf64, not reserved by TS
18661-1); the headers are made to arrange for sqrt to be called in
that case instead.

The DIAG_* calls in sysdeps/ieee754/soft-fp/s_dsqrtl.c are because
they were observed to be needed in GCC 7 testing of
riscv32-linux-gnu-rv32imac-ilp32.  The other sysdeps/ieee754/soft-fp/
files added didn't need such DIAG_* in any configuration I tested with
build-many-glibcs.py, but if they do turn out to be needed in more
files with some other configuration / GCC version, they can always be
added there.

I reused the same test inputs in auto-libm-test-in as for
non-narrowing sqrt rather than adding extra or separate inputs for
narrowing sqrt.  The tests in libm-test-narrow-sqrt.inc also follow
those for non-narrowing sqrt.

Tested as followed: natively with the full glibc testsuite for x86_64
(GCC 11, 7, 6) and x86 (GCC 11); with build-many-glibcs.py with GCC
11, 7 and 6; cross testing of math/ tests for powerpc64le, powerpc32
hard float, mips64 (all three ABIs, both hard and soft float).  The
different GCC versions are to cover the different cases in tgmath.h
and tgmath.h tests properly (GCC 6 has _Float* only as typedefs in
glibc headers, GCC 7 has proper _Float* support, GCC 8 adds
__builtin_tgmath).

---

Committed.  The posted diff omits the large
math/auto-libm-test-out-narrow-sqrt file that would otherwise form the
bulk of the diff.

The narrowing fma functions are the only remaining functions from TS
18661-1 to implement after this patch; they should be very similar to
narrowing sqrt.
diff mbox series

Patch

diff --git a/NEWS b/NEWS
index 5b014fabbf..838381f562 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,13 @@  Major new features:
   in various downstream distributions.  The locale is not built into
   glibc, and must be installed.
 
+* <math.h> functions that round their results to a narrower type, and
+  corresponding <tgmath.h> macros, are added from TS 18661-1:2014, TS
+  18661-3:2015 and draft ISO C2X:
+
+  - fsqrt, fsqrtl, dsqrtl and corresponding fMsqrtfN, fMsqrtfNx,
+    fMxsqrtfN and fMxsqrtfNx functions.
+
 Deprecated and removed features, and other changes affecting compatibility:
 
   [Add deprecations, removals and changes affecting compatibility here]
diff --git a/manual/arith.texi b/manual/arith.texi
index 75eaf67fe7..edf1fd71f8 100644
--- a/manual/arith.texi
+++ b/manual/arith.texi
@@ -2270,6 +2270,25 @@  function without any intermediate rounding to the type of the
 arguments.
 @end deftypefun
 
+@deftypefun float fsqrt (double @var{x})
+@deftypefunx float fsqrtl (long double @var{x})
+@deftypefunx double dsqrtl (long double @var{x})
+@deftypefunx _FloatM fMsqrtfN (_Float@var{N} @var{x})
+@deftypefunx _FloatM fMsqrtfNx (_Float@var{N}x @var{x})
+@deftypefunx _FloatMx fMxsqrtfN (_Float@var{N} @var{x})
+@deftypefunx _FloatMx fMxsqrtfNx (_Float@var{N}x @var{x})
+@standards{TS 18661-1:2014, math.h}
+@standardsx{fMsqrtfN, TS 18661-3:2015, math.h}
+@standardsx{fMsqrtfNx, TS 18661-3:2015, math.h}
+@standardsx{fMxsqrtfN, TS 18661-3:2015, math.h}
+@standardsx{fMxsqrtfNx, TS 18661-3:2015, math.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+These functions, from TS 18661-1:2014 and TS 18661-3:2015, return the
+square root of @var{x}, rounded once to the return type of the
+function without any intermediate rounding to the type of the
+arguments.
+@end deftypefun
+
 @node Complex Numbers
 @section Complex Numbers
 @pindex complex.h
diff --git a/math/Makefile b/math/Makefile
index ceb1eb2085..987e9841f9 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -91,7 +91,7 @@  libm-compat-calls =							\
 	w_lgammaF_r_compat w_lgammaF_compat2 w_expF_compat		\
 	w_lgamma_compatF k_standardF
 
-libm-narrow-fns = add div mul sub
+libm-narrow-fns = add div mul sqrt sub
 libm-narrow-types-basic = s_fF s_f32xFf64
 libm-narrow-types-ldouble-yes = s_fFl s_dFl
 libm-narrow-types-float128-yes = s_f32Ff128 s_f64Ff128 s_f64xFf128
@@ -299,7 +299,7 @@  libm-test-funcs-noauto = canonicalize ceil cimag conj copysign cproj creal \
 			 significand totalorder totalordermag trunc ufromfp \
 			 ufromfpx compat_totalorder compat_totalordermag
 libm-test-funcs-compat = compat_totalorder compat_totalordermag
-libm-test-funcs-narrow = add div mul sub
+libm-test-funcs-narrow = add div mul sqrt sub
 libm-test-funcs-all = $(libm-test-funcs-auto) $(libm-test-funcs-noauto)
 libm-test-c-auto = $(foreach f,$(libm-test-funcs-auto),libm-test-$(f).c)
 libm-test-c-noauto = $(foreach f,$(libm-test-funcs-noauto),libm-test-$(f).c)
@@ -664,6 +664,7 @@  CFLAGS-s_ctanh.c += -fno-builtin-ctanhl
 CFLAGS-s_dadd.c += -fno-builtin-daddl
 CFLAGS-s_ddiv.c += -fno-builtin-ddivl
 CFLAGS-s_dmul.c += -fno-builtin-dmull
+CFLAGS-s_dsqrt.c += -fno-builtin-dsqrtl
 CFLAGS-s_dsub.c += -fno-builtin-dsubl
 CFLAGS-s_erf.c += -fno-builtin-erfl
 CFLAGS-s_erfc.c += -fno-builtin-erfcl
@@ -687,6 +688,7 @@  CFLAGS-s_fmul.c += -fno-builtin-fmull
 CFLAGS-s_frexp.c += -fno-builtin-frexpl
 CFLAGS-s_fromfp.c += -fno-builtin-fromfpl
 CFLAGS-s_fromfpx.c += -fno-builtin-fromfpxl
+CFLAGS-s_fsqrt.c += -fno-builtin-fsqrtl
 CFLAGS-s_fsub.c += -fno-builtin-fsubl
 CFLAGS-s_gamma.c += -fno-builtin-gammal
 CFLAGS-s_getpayload.c += -fno-builtin-getpayloadl
diff --git a/math/Versions b/math/Versions
index 5b3c321490..b121b454cd 100644
--- a/math/Versions
+++ b/math/Versions
@@ -593,4 +593,13 @@  libm {
   GLIBC_2.32 {
     exp10f;
   }
+  GLIBC_2.35 {
+    # Functions not involving _Float64x or _Float128, for all configurations.
+    fsqrt; fsqrtl; dsqrtl;
+    f32sqrtf32x; f32sqrtf64; f32xsqrtf64;
+    # Functions involving _Float64x or _Float128, for some configurations.
+    f32sqrtf64x; f32sqrtf128;
+    f32xsqrtf64x; f32xsqrtf128; f64sqrtf64x; f64sqrtf128;
+    f64xsqrtf128;
+  }
 }
diff --git a/math/bits/mathcalls-narrow.h b/math/bits/mathcalls-narrow.h
index 4f28f41d13..287896d769 100644
--- a/math/bits/mathcalls-narrow.h
+++ b/math/bits/mathcalls-narrow.h
@@ -29,5 +29,8 @@  __MATHCALL_NARROW (__MATHCALL_NAME (div), __MATHCALL_REDIR_NAME (div), 2);
 /* Multiply.  */
 __MATHCALL_NARROW (__MATHCALL_NAME (mul), __MATHCALL_REDIR_NAME (mul), 2);
 
+/* Square root.  */
+__MATHCALL_NARROW (__MATHCALL_NAME (sqrt), __MATHCALL_REDIR_NAME2 (sqrt), 1);
+
 /* Subtract.  */
 __MATHCALL_NARROW (__MATHCALL_NAME (sub), __MATHCALL_REDIR_NAME (sub), 2);
diff --git a/math/gen-tgmath-tests.py b/math/gen-tgmath-tests.py
index 364963da65..858fd4c309 100755
--- a/math/gen-tgmath-tests.py
+++ b/math/gen-tgmath-tests.py
@@ -696,7 +696,8 @@  class Tests(object):
         self.add_tests('fromfpx', 'intmax_t', ['r', 'int', 'unsigned int'])
         self.add_tests('ufromfp', 'uintmax_t', ['r', 'int', 'unsigned int'])
         self.add_tests('ufromfpx', 'uintmax_t', ['r', 'int', 'unsigned int'])
-        for fn in ('add', 'div', 'mul', 'sub'):
+        for fn, args in (('add', 2), ('div', 2), ('mul', 2), ('sqrt', 1),
+                         ('sub', 2)):
             for ret, prefix in (('float', 'f'),
                                 ('double', 'd'),
                                 ('_Float16', 'f16'),
@@ -705,7 +706,7 @@  class Tests(object):
                                 ('_Float128', 'f128'),
                                 ('_Float32x', 'f32x'),
                                 ('_Float64x', 'f64x')):
-                self.add_tests(prefix + fn, ret, ['r', 'r'])
+                self.add_tests(prefix + fn, ret, ['r'] * args)
         # Miscellaneous functions.
         self.add_tests('scalb', 's', ['s', 's'])
 
diff --git a/math/libm-test-driver.c b/math/libm-test-driver.c
index 0a430a8606..ae0b312708 100644
--- a/math/libm-test-driver.c
+++ b/math/libm-test-driver.c
@@ -169,6 +169,16 @@  struct test_fj_f_data
   } rd, rn, rz, ru;
 };
 #ifdef ARG_FLOAT
+struct test_a_f_data
+{
+  const char *arg_str;
+  ARG_FLOAT arg;
+  struct
+  {
+    FLOAT expected;
+    int exceptions;
+  } rd, rn, rz, ru;
+};
 struct test_aa_f_data
 {
   const char *arg_str;
@@ -459,7 +469,7 @@  struct test_Ff_b1_data
 
 /* Run an individual test, including any required setup and checking
    of results, or loop over all tests in an array.  */
-#define RUN_TEST_f_f(ARG_STR, FUNC_NAME, ARG, EXPECTED,			\
+#define RUN_TEST_1_f(ARG_STR, FUNC_NAME, ARG, EXPECTED,			\
 		     EXCEPTIONS)					\
   do									\
     if (enable_test (EXCEPTIONS))					\
@@ -470,13 +480,15 @@  struct test_Ff_b1_data
 	COMMON_TEST_CLEANUP;						\
       }									\
   while (0)
-#define RUN_TEST_LOOP_f_f(FUNC_NAME, ARRAY, ROUNDING_MODE)		\
+#define RUN_TEST_LOOP_1_f(FUNC_NAME, ARRAY, ROUNDING_MODE)		\
   IF_ROUND_INIT_ ## ROUNDING_MODE					\
     for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++)	\
-      RUN_TEST_f_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg,	\
+      RUN_TEST_1_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg,	\
 		    (ARRAY)[i].RM_##ROUNDING_MODE.expected,		\
 		    (ARRAY)[i].RM_##ROUNDING_MODE.exceptions);		\
   ROUND_RESTORE_ ## ROUNDING_MODE
+#define RUN_TEST_LOOP_f_f RUN_TEST_LOOP_1_f
+#define RUN_TEST_LOOP_a_f RUN_TEST_LOOP_1_f
 #define RUN_TEST_fp_f(ARG_STR, FUNC_NAME, ARG, EXPECTED,		\
 		     EXCEPTIONS)					\
   do									\
diff --git a/math/libm-test-narrow-sqrt.inc b/math/libm-test-narrow-sqrt.inc
new file mode 100644
index 0000000000..7bf8c43ed9
--- /dev/null
+++ b/math/libm-test-narrow-sqrt.inc
@@ -0,0 +1,56 @@ 
+/* Test narrowing sqrt.
+   Copyright (C) 1997-2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include "libm-test-driver.c"
+
+static const struct test_a_f_data sqrt_test_data[] =
+  {
+    TEST_a_f (sqrt, arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_a_f (sqrt, -arg_qnan_value, qnan_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_a_f (sqrt, arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_a_f (sqrt, -arg_snan_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
+    TEST_a_f (sqrt, arg_plus_infty, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+
+    /* sqrt (x) == qNaN plus invalid exception for x < 0.  */
+    TEST_a_f (sqrt, -1, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_a_f (sqrt, -1.1L, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_a_f (sqrt, -arg_min_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_a_f (sqrt, -arg_min_subnorm_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_a_f (sqrt, -arg_max_value, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+    TEST_a_f (sqrt, arg_minus_infty, qnan_value, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM),
+
+    AUTO_TESTS_a_f (sqrt),
+  };
+
+static void
+sqrt_test (void)
+{
+  ALL_RM_TEST (sqrt, 1, sqrt_test_data, RUN_TEST_LOOP_a_f, END);
+}
+
+static void
+do_test (void)
+{
+  sqrt_test ();
+}
+
+/*
+ * Local Variables:
+ * mode:c
+ * End:
+ */
diff --git a/math/math-narrow.h b/math/math-narrow.h
index dadbe5cfba..93d1b4c52a 100644
--- a/math/math-narrow.h
+++ b/math/math-narrow.h
@@ -27,16 +27,20 @@ 
 #include <math-barriers.h>
 #include <math_private.h>
 #include <fenv_private.h>
+#include <math-narrow-alias.h>
 
 /* Carry out a computation using round-to-odd.  The computation is
    EXPR; the union type in which to store the result is UNION and the
    subfield of the "ieee" field of that union with the low part of the
-   mantissa is MANTISSA; SUFFIX is the suffix for the libc_fe* macros
-   to ensure that the correct rounding mode is used, for platforms
-   with multiple rounding modes where those macros set only the
-   relevant mode.  This macro does not work correctly if the sign of
-   an exact zero result depends on the rounding mode, so that case
-   must be checked for separately.  */
+   mantissa is MANTISSA; SUFFIX is the suffix for both underlying libm
+   functions for the argument type (for computations where a libm
+   function rather than a C operator is used when argument and result
+   types are the same) and the libc_fe* macros to ensure that the
+   correct rounding mode is used, for platforms with multiple rounding
+   modes where those macros set only the relevant mode.  This macro
+   does not work correctly if the sign of an exact zero result depends
+   on the rounding mode, so that case must be checked for
+   separately.  */
 #define ROUND_TO_ODD(EXPR, UNION, SUFFIX, MANTISSA)			\
   ({									\
     fenv_t env;								\
@@ -273,85 +277,58 @@ 
     }						\
   while (0)
 
-/* The following macros declare aliases for a narrowing function.  The
-   sole argument is the base name of a family of functions, such as
-   "add".  If any platform changes long double format after the
-   introduction of narrowing functions, in a way requiring symbol
-   versioning compatibility, additional variants of these macros will
-   be needed.  */
-
-#define libm_alias_float_double_main(func)	\
-  weak_alias (__f ## func, f ## func)		\
-  weak_alias (__f ## func, f32 ## func ## f64)	\
-  weak_alias (__f ## func, f32 ## func ## f32x)
-
-#ifdef NO_LONG_DOUBLE
-# define libm_alias_float_double(func)		\
-  libm_alias_float_double_main (func)		\
-  weak_alias (__f ## func, f ## func ## l)
-#else
-# define libm_alias_float_double(func)		\
-  libm_alias_float_double_main (func)
-#endif
-
-#define libm_alias_float32x_float64_main(func)			\
-  weak_alias (__f32x ## func ## f64, f32x ## func ## f64)
-
-#ifdef NO_LONG_DOUBLE
-# define libm_alias_float32x_float64(func)		\
-  libm_alias_float32x_float64_main (func)		\
-  weak_alias (__f32x ## func ## f64, d ## func ## l)
-#elif defined __LONG_DOUBLE_MATH_OPTIONAL
-# define libm_alias_float32x_float64(func)			\
-  libm_alias_float32x_float64_main (func)			\
-  weak_alias (__f32x ## func ## f64, __nldbl_d ## func ## l)
-#else
-# define libm_alias_float32x_float64(func)	\
-  libm_alias_float32x_float64_main (func)
-#endif
-
-#if __HAVE_FLOAT128 && !__HAVE_DISTINCT_FLOAT128
-# define libm_alias_float_ldouble_f128(func)		\
-  weak_alias (__f ## func ## l, f32 ## func ## f128)
-# define libm_alias_double_ldouble_f128(func)		\
-  weak_alias (__d ## func ## l, f32x ## func ## f128)	\
-  weak_alias (__d ## func ## l, f64 ## func ## f128)
-#else
-# define libm_alias_float_ldouble_f128(func)
-# define libm_alias_double_ldouble_f128(func)
-#endif
-
-#if __HAVE_FLOAT64X_LONG_DOUBLE
-# define libm_alias_float_ldouble_f64x(func)		\
-  weak_alias (__f ## func ## l, f32 ## func ## f64x)
-# define libm_alias_double_ldouble_f64x(func)		\
-  weak_alias (__d ## func ## l, f32x ## func ## f64x)	\
-  weak_alias (__d ## func ## l, f64 ## func ## f64x)
-#else
-# define libm_alias_float_ldouble_f64x(func)
-# define libm_alias_double_ldouble_f64x(func)
-#endif
-
-#define libm_alias_float_ldouble(func)		\
-  weak_alias (__f ## func ## l, f ## func ## l) \
-  libm_alias_float_ldouble_f128 (func)		\
-  libm_alias_float_ldouble_f64x (func)
-
-#define libm_alias_double_ldouble(func)		\
-  weak_alias (__d ## func ## l, d ## func ## l) \
-  libm_alias_double_ldouble_f128 (func)		\
-  libm_alias_double_ldouble_f64x (func)
-
-#define libm_alias_float64x_float128(func)			\
-  weak_alias (__f64x ## func ## f128, f64x ## func ## f128)
-
-#define libm_alias_float32_float128_main(func)			\
-  weak_alias (__f32 ## func ## f128, f32 ## func ## f128)
+/* Check for error conditions from a narrowing square root function
+   returning RET with argument X and set errno as needed.  Overflow
+   and underflow can occur for finite positive arguments and a domain
+   error for negative arguments.  */
+#define CHECK_NARROW_SQRT(RET, X)		\
+  do						\
+    {						\
+      if (!isfinite (RET))			\
+	{					\
+	  if (isnan (RET))			\
+	    {					\
+	      if (!isnan (X))			\
+		__set_errno (EDOM);		\
+	    }					\
+	  else if (isfinite (X))		\
+	    __set_errno (ERANGE);		\
+	}					\
+      else if ((RET) == 0 && (X) != 0)		\
+	__set_errno (ERANGE);			\
+    }						\
+  while (0)
 
-#define libm_alias_float64_float128_main(func)			\
-  weak_alias (__f64 ## func ## f128, f64 ## func ## f128)	\
-  weak_alias (__f64 ## func ## f128, f32x ## func ## f128)
+/* Implement narrowing square root using round-to-odd.  The argument
+   is X, the return type is TYPE and UNION, MANTISSA and SUFFIX are as
+   for ROUND_TO_ODD.  */
+#define NARROW_SQRT_ROUND_TO_ODD(X, TYPE, UNION, SUFFIX, MANTISSA)	\
+  do									\
+    {									\
+      TYPE ret;								\
+									\
+      ret = (TYPE) ROUND_TO_ODD (sqrt ## SUFFIX (math_opt_barrier (X)),	\
+				 UNION, SUFFIX, MANTISSA);		\
+									\
+      CHECK_NARROW_SQRT (ret, (X));					\
+      return ret;							\
+    }									\
+  while (0)
 
-#include <math-narrow-alias-float128.h>
+/* Implement a narrowing square root function where no attempt is made
+   to be correctly rounding (this only applies to IBM long double; the
+   case where the function is not actually narrowing is handled by
+   aliasing other sqrt functions in libm, not using this macro).  The
+   argument is X and the return type is TYPE.  */
+#define NARROW_SQRT_TRIVIAL(X, TYPE, SUFFIX)	\
+  do						\
+    {						\
+      TYPE ret;					\
+						\
+      ret = (TYPE) (sqrt ## SUFFIX (X));	\
+      CHECK_NARROW_SQRT (ret, (X));		\
+      return ret;				\
+    }						\
+  while (0)
 
 #endif /* math-narrow.h.  */
diff --git a/math/math.h b/math/math.h
index 6b7ac79122..404d24dae6 100644
--- a/math/math.h
+++ b/math/math.h
@@ -573,11 +573,13 @@  extern double __REDIRECT_NTH (nexttoward, (double __x, long double __y),
 # define __MATHCALL_NAME(name) f ## name ## l
 # ifdef __LDBL_COMPAT
 #  define __MATHCALL_REDIR_NAME(name) f ## name
+#  define __MATHCALL_REDIR_NAME2(name) f ## name
 #  undef __MATHCALL_NARROW
 #  define __MATHCALL_NARROW(func, redir, nargs) \
   __MATHCALL_NARROW_REDIR (func, redir, nargs)
 # elif __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
 #  define __MATHCALL_REDIR_NAME(name) __ ## f32 ## name ## ieee128
+#  define __MATHCALL_REDIR_NAME2(name) __ ## f32 ## name ## ieee128
 #  undef __MATHCALL_NARROW
 #  define __MATHCALL_NARROW(func, redir, nargs) \
   __MATHCALL_NARROW_REDIR (func, redir, nargs)
@@ -589,6 +591,7 @@  extern double __REDIRECT_NTH (nexttoward, (double __x, long double __y),
 # if defined __LDBL_COMPAT \
      || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
 #  undef __MATHCALL_REDIR_NAME
+#  undef __MATHCALL_REDIR_NAME2
 #  undef __MATHCALL_NARROW
 #  define __MATHCALL_NARROW(func, redir, nargs) \
   __MATHCALL_NARROW_NORMAL (func, nargs)
@@ -599,11 +602,13 @@  extern double __REDIRECT_NTH (nexttoward, (double __x, long double __y),
 # define __MATHCALL_NAME(name) d ## name ## l
 # ifdef __LDBL_COMPAT
 #  define __MATHCALL_REDIR_NAME(name) __nldbl_d ## name ## l
+#  define __MATHCALL_REDIR_NAME2(name) name
 #  undef __MATHCALL_NARROW
 #  define __MATHCALL_NARROW(func, redir, nargs) \
   __MATHCALL_NARROW_REDIR (func, redir, nargs)
 # elif __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
 #  define __MATHCALL_REDIR_NAME(name) __ ## f64 ## name ## ieee128
+#  define __MATHCALL_REDIR_NAME2(name) __ ## f64 ## name ## ieee128
 #  undef __MATHCALL_NARROW
 #  define __MATHCALL_NARROW(func, redir, nargs) \
   __MATHCALL_NARROW_REDIR (func, redir, nargs)
@@ -615,6 +620,7 @@  extern double __REDIRECT_NTH (nexttoward, (double __x, long double __y),
 # if defined __LDBL_COMPAT \
      || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
 #  undef __MATHCALL_REDIR_NAME
+#  undef __MATHCALL_REDIR_NAME2
 #  undef __MATHCALL_NARROW
 #  define __MATHCALL_NARROW(func, redir, nargs) \
   __MATHCALL_NARROW_NORMAL (func, nargs)
diff --git a/math/tgmath.h b/math/tgmath.h
index b55cb39c93..5f19cf4821 100644
--- a/math/tgmath.h
+++ b/math/tgmath.h
@@ -53,11 +53,17 @@ 
       || (__HAVE_FLOAT128 && !__HAVE_FLOAT64X))
 #  error "Unsupported combination of types for <tgmath.h>."
 # endif
+# define __TGMATH_1_NARROW_D(F, X)		\
+  (F ## l (X))
 # define __TGMATH_2_NARROW_D(F, X, Y)		\
   (F ## l (X, Y))
+# define __TGMATH_1_NARROW_F64X(F, X)		\
+  (F ## f128 (X))
 # define __TGMATH_2_NARROW_F64X(F, X, Y)	\
   (F ## f128 (X, Y))
 # if !__HAVE_FLOAT128
+#  define __TGMATH_1_NARROW_F32X(F, X)		\
+  (F ## f64 (X))
 #  define __TGMATH_2_NARROW_F32X(F, X, Y)	\
   (F ## f64 (X, Y))
 # endif
@@ -127,15 +133,25 @@ 
     __TG_F64X_ARG (X) __TG_F128X_ARG (X)	\
     __TG_F64_ARG (X) __TG_F128_ARG (X)
 
+#  define __TGMATH_1_NARROW_F(F, X)				\
+  __builtin_tgmath (__TGMATH_NARROW_FUNCS_F (F) (X))
 #  define __TGMATH_2_NARROW_F(F, X, Y)				\
   __builtin_tgmath (__TGMATH_NARROW_FUNCS_F (F) (X), (Y))
+#  define __TGMATH_1_NARROW_F16(F, X)				\
+  __builtin_tgmath (__TGMATH_NARROW_FUNCS_F16 (F) (X))
 #  define __TGMATH_2_NARROW_F16(F, X, Y)			\
   __builtin_tgmath (__TGMATH_NARROW_FUNCS_F16 (F) (X), (Y))
+#  define __TGMATH_1_NARROW_F32(F, X)				\
+  __builtin_tgmath (__TGMATH_NARROW_FUNCS_F32 (F) (X))
 #  define __TGMATH_2_NARROW_F32(F, X, Y)			\
   __builtin_tgmath (__TGMATH_NARROW_FUNCS_F32 (F) (X), (Y))
+#  define __TGMATH_1_NARROW_F64(F, X)				\
+  __builtin_tgmath (__TGMATH_NARROW_FUNCS_F64 (F) (X))
 #  define __TGMATH_2_NARROW_F64(F, X, Y)			\
   __builtin_tgmath (__TGMATH_NARROW_FUNCS_F64 (F) (X), (Y))
 #  if __HAVE_FLOAT128
+#   define __TGMATH_1_NARROW_F32X(F, X)				\
+  __builtin_tgmath (__TGMATH_NARROW_FUNCS_F32X (F) (X))
 #   define __TGMATH_2_NARROW_F32X(F, X, Y)			\
   __builtin_tgmath (__TGMATH_NARROW_FUNCS_F32X (F) (X), (Y))
 #  endif
@@ -540,6 +556,10 @@ 
 				   + (__tgmath_complex_type (Val2)) 0))	      \
 			  Cfct##f (Val1, Val2))))
 
+#  define __TGMATH_1_NARROW_F(F, X)					\
+  (__extension__ (sizeof ((__tgmath_real_type (X)) 0) > sizeof (double) \
+		  ? F ## l (X)						\
+		  : F (X)))
 #  define __TGMATH_2_NARROW_F(F, X, Y)					\
   (__extension__ (sizeof ((__tgmath_real_type (X)) 0			\
 			  + (__tgmath_real_type (Y)) 0) > sizeof (double) \
@@ -563,18 +583,33 @@ 
    have type _Float64, so the *f64 functions are preferred for f32x*
    macros when no argument has a wider floating-point type.  */
 #  if __HAVE_FLOAT64X_LONG_DOUBLE && __HAVE_DISTINCT_FLOAT128
+#   define __TGMATH_1_NARROW_F32(F, X)					\
+  (__extension__ (sizeof ((__tgmath_real_type (X)) 0) > sizeof (_Float64) \
+		  ? __TGMATH_F128 ((X), F, (X))				\
+		  F ## f64x (X)						\
+		  : F ## f64 (X)))
 #   define __TGMATH_2_NARROW_F32(F, X, Y)				\
   (__extension__ (sizeof ((__tgmath_real_type (X)) 0			\
 			  + (__tgmath_real_type (Y)) 0) > sizeof (_Float64) \
 		  ? __TGMATH_F128 ((X) + (Y), F, (X, Y))		\
 		  F ## f64x (X, Y)					\
 		  : F ## f64 (X, Y)))
+#   define __TGMATH_1_NARROW_F64(F, X)					\
+  (__extension__ (sizeof ((__tgmath_real_type (X)) 0) > sizeof (_Float64) \
+		  ? __TGMATH_F128 ((X), F, (X))				\
+		  F ## f64x (X)						\
+		  : F ## f128 (X)))
 #   define __TGMATH_2_NARROW_F64(F, X, Y)				\
   (__extension__ (sizeof ((__tgmath_real_type (X)) 0			\
 			  + (__tgmath_real_type (Y)) 0) > sizeof (_Float64) \
 		  ? __TGMATH_F128 ((X) + (Y), F, (X, Y))		\
 		  F ## f64x (X, Y)					\
 		  : F ## f128 (X, Y)))
+#   define __TGMATH_1_NARROW_F32X(F, X)					\
+  (__extension__ (sizeof ((__tgmath_real_type (X)) 0) > sizeof (_Float64) \
+		  ? __TGMATH_F128 ((X), F, (X))				\
+		  F ## f64x (X)						\
+		  : F ## f64 (X)))
 #   define __TGMATH_2_NARROW_F32X(F, X, Y)				\
   (__extension__ (sizeof ((__tgmath_real_type (X)) 0			\
 			  + (__tgmath_real_type (Y)) 0) > sizeof (_Float64) \
@@ -582,19 +617,31 @@ 
 		  F ## f64x (X, Y)					\
 		  : F ## f64 (X, Y)))
 #  elif __HAVE_FLOAT128
+#   define __TGMATH_1_NARROW_F32(F, X)					\
+  (__extension__ (sizeof ((__tgmath_real_type (X)) 0) > sizeof (_Float64) \
+		  ? F ## f128 (X)					\
+		  : F ## f64 (X)))
 #   define __TGMATH_2_NARROW_F32(F, X, Y)				\
   (__extension__ (sizeof ((__tgmath_real_type (X)) 0			\
 			  + (__tgmath_real_type (Y)) 0) > sizeof (_Float64) \
 		  ? F ## f128 (X, Y)					\
 		  : F ## f64 (X, Y)))
+#   define __TGMATH_1_NARROW_F64(F, X)		\
+  (F ## f128 (X))
 #   define __TGMATH_2_NARROW_F64(F, X, Y)	\
   (F ## f128 (X, Y))
+#   define __TGMATH_1_NARROW_F32X(F, X)					\
+  (__extension__ (sizeof ((__tgmath_real_type (X)) 0) > sizeof (_Float32x) \
+		  ? F ## f64x (X)					\
+		  : F ## f64 (X)))
 #   define __TGMATH_2_NARROW_F32X(F, X, Y)				\
   (__extension__ (sizeof ((__tgmath_real_type (X)) 0			\
 			  + (__tgmath_real_type (Y)) 0) > sizeof (_Float32x) \
 		  ? F ## f64x (X, Y)					\
 		  : F ## f64 (X, Y)))
 #  else
+#   define __TGMATH_1_NARROW_F32(F, X)		\
+  (F ## f64 (X))
 #   define __TGMATH_2_NARROW_F32(F, X, Y)	\
   (F ## f64 (X, Y))
 #  endif
@@ -865,6 +912,10 @@ 
 # define fsub(Val1, Val2) __TGMATH_2_NARROW_F (fsub, Val1, Val2)
 # define dsub(Val1, Val2) __TGMATH_2_NARROW_D (dsub, Val1, Val2)
 
+/* Square root.  */
+# define fsqrt(Val) __TGMATH_1_NARROW_F (fsqrt, Val)
+# define dsqrt(Val) __TGMATH_1_NARROW_D (dsqrt, Val)
+
 #endif
 
 #if __GLIBC_USE (IEC_60559_TYPES_EXT)
@@ -874,6 +925,7 @@ 
 #  define f16div(Val1, Val2) __TGMATH_2_NARROW_F16 (f16div, Val1, Val2)
 #  define f16mul(Val1, Val2) __TGMATH_2_NARROW_F16 (f16mul, Val1, Val2)
 #  define f16sub(Val1, Val2) __TGMATH_2_NARROW_F16 (f16sub, Val1, Val2)
+#  define f16sqrt(Val) __TGMATH_1_NARROW_F16 (f16sqrt, Val)
 # endif
 
 # if __HAVE_FLOAT32
@@ -881,6 +933,7 @@ 
 #  define f32div(Val1, Val2) __TGMATH_2_NARROW_F32 (f32div, Val1, Val2)
 #  define f32mul(Val1, Val2) __TGMATH_2_NARROW_F32 (f32mul, Val1, Val2)
 #  define f32sub(Val1, Val2) __TGMATH_2_NARROW_F32 (f32sub, Val1, Val2)
+#  define f32sqrt(Val) __TGMATH_1_NARROW_F32 (f32sqrt, Val)
 # endif
 
 # if __HAVE_FLOAT64 && (__HAVE_FLOAT64X || __HAVE_FLOAT128)
@@ -888,6 +941,7 @@ 
 #  define f64div(Val1, Val2) __TGMATH_2_NARROW_F64 (f64div, Val1, Val2)
 #  define f64mul(Val1, Val2) __TGMATH_2_NARROW_F64 (f64mul, Val1, Val2)
 #  define f64sub(Val1, Val2) __TGMATH_2_NARROW_F64 (f64sub, Val1, Val2)
+#  define f64sqrt(Val) __TGMATH_1_NARROW_F64 (f64sqrt, Val)
 # endif
 
 # if __HAVE_FLOAT32X
@@ -895,6 +949,7 @@ 
 #  define f32xdiv(Val1, Val2) __TGMATH_2_NARROW_F32X (f32xdiv, Val1, Val2)
 #  define f32xmul(Val1, Val2) __TGMATH_2_NARROW_F32X (f32xmul, Val1, Val2)
 #  define f32xsub(Val1, Val2) __TGMATH_2_NARROW_F32X (f32xsub, Val1, Val2)
+#  define f32xsqrt(Val) __TGMATH_1_NARROW_F32X (f32xsqrt, Val)
 # endif
 
 # if __HAVE_FLOAT64X && (__HAVE_FLOAT128X || __HAVE_FLOAT128)
@@ -902,6 +957,7 @@ 
 #  define f64xdiv(Val1, Val2) __TGMATH_2_NARROW_F64X (f64xdiv, Val1, Val2)
 #  define f64xmul(Val1, Val2) __TGMATH_2_NARROW_F64X (f64xmul, Val1, Val2)
 #  define f64xsub(Val1, Val2) __TGMATH_2_NARROW_F64X (f64xsub, Val1, Val2)
+#  define f64xsqrt(Val) __TGMATH_1_NARROW_F64X (f64xsqrt, Val)
 # endif
 
 #endif
diff --git a/math/w_sqrt_compat.c b/math/w_sqrt_compat.c
index 13402de76e..f35882086d 100644
--- a/math/w_sqrt_compat.c
+++ b/math/w_sqrt_compat.c
@@ -16,9 +16,14 @@ 
    <https://www.gnu.org/licenses/>.  */
 
 #define NO_MATH_REDIRECT
+#define dsqrtl __hide_dsqrtl
+#define f32xsqrtf64 __hide_f32xsqrtf64
 #include <math.h>
+#undef dsqrtl
+#undef f32xsqrtf64
 #include <math_private.h>
 #include <math-svid-compat.h>
+#include <math-narrow-alias.h>
 #include <libm-alias-double.h>
 
 
@@ -33,4 +38,5 @@  __sqrt (double x)
   return __ieee754_sqrt (x);
 }
 libm_alias_double (__sqrt, sqrt)
+libm_alias_double_narrow (__sqrt, sqrt)
 #endif
diff --git a/math/w_sqrt_template.c b/math/w_sqrt_template.c
index b6f97d7526..8c53d5108e 100644
--- a/math/w_sqrt_template.c
+++ b/math/w_sqrt_template.c
@@ -24,8 +24,15 @@ 
 # define NO_MATH_REDIRECT
 # include <errno.h>
 # include <fenv.h>
+# define dsqrtl __hide_dsqrtl
+# define f32xsqrtf64 __hide_f32xsqrtf64
+# define f64xsqrtf128 __hide_f64xsqrtf128
 # include <math.h>
+# undef dsqrtl
+# undef f32xsqrtf64
+# undef f64xsqrtf128
 # include <math_private.h>
+# include <math-narrow-alias.h>
 
 FLOAT
 M_DECL_FUNC (__sqrt) (FLOAT x)
@@ -36,5 +43,6 @@  M_DECL_FUNC (__sqrt) (FLOAT x)
   return M_SUF (__ieee754_sqrt) (x);
 }
 declare_mgen_alias (__sqrt, sqrt)
+declare_mgen_alias_narrow (__sqrt, sqrt)
 
 #endif /* __USE_WRAPPER_TEMPLATE.  */
diff --git a/math/w_sqrtl_compat.c b/math/w_sqrtl_compat.c
index e9ab9a0e44..ec041e7361 100644
--- a/math/w_sqrtl_compat.c
+++ b/math/w_sqrtl_compat.c
@@ -16,9 +16,12 @@ 
    <https://www.gnu.org/licenses/>.  */
 
 #define NO_MATH_REDIRECT
+#define f64xsqrtf128 __hide_f64xsqrtf128
 #include <math.h>
+#undef f64xsqrtf128
 #include <math_private.h>
 #include <math-svid-compat.h>
+#include <math-narrow-alias.h>
 #include <libm-alias-ldouble.h>
 
 
@@ -33,4 +36,5 @@  __sqrtl (long double x)
   return __ieee754_sqrtl (x);
 }
 libm_alias_ldouble (__sqrt, sqrt)
+libm_alias_ldouble_narrow (__sqrt, sqrt)
 #endif
diff --git a/sysdeps/generic/math-narrow-alias.h b/sysdeps/generic/math-narrow-alias.h
new file mode 100644
index 0000000000..44c4ab6f06
--- /dev/null
+++ b/sysdeps/generic/math-narrow-alias.h
@@ -0,0 +1,135 @@ 
+/* Alias macros for functions returning a narrower type.
+   Copyright (C) 2018-2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef	_MATH_NARROW_ALIAS_H
+#define	_MATH_NARROW_ALIAS_H	1
+
+#include <bits/floatn.h>
+#include <bits/long-double.h>
+
+/* The following macros declare aliases for a narrowing function.  The
+   sole argument is the base name of a family of functions, such as
+   "add".  If any platform changes long double format after the
+   introduction of narrowing functions, in a way requiring symbol
+   versioning compatibility, additional variants of these macros will
+   be needed.  */
+
+#define libm_alias_float_double_main(func)	\
+  weak_alias (__f ## func, f ## func)		\
+  weak_alias (__f ## func, f32 ## func ## f64)	\
+  weak_alias (__f ## func, f32 ## func ## f32x)
+
+#ifdef NO_LONG_DOUBLE
+# define libm_alias_float_double(func)		\
+  libm_alias_float_double_main (func)		\
+  weak_alias (__f ## func, f ## func ## l)
+#else
+# define libm_alias_float_double(func)		\
+  libm_alias_float_double_main (func)
+#endif
+
+#define libm_alias_float32x_float64_main(func)			\
+  weak_alias (__f32x ## func ## f64, f32x ## func ## f64)
+
+#ifdef NO_LONG_DOUBLE
+# define libm_alias_float32x_float64(func)		\
+  libm_alias_float32x_float64_main (func)		\
+  weak_alias (__f32x ## func ## f64, d ## func ## l)
+#elif defined __LONG_DOUBLE_MATH_OPTIONAL
+# define libm_alias_float32x_float64(func)			\
+  libm_alias_float32x_float64_main (func)			\
+  weak_alias (__f32x ## func ## f64, __nldbl_d ## func ## l)
+#else
+# define libm_alias_float32x_float64(func)	\
+  libm_alias_float32x_float64_main (func)
+#endif
+
+#if __HAVE_FLOAT128 && !__HAVE_DISTINCT_FLOAT128
+# define libm_alias_float_ldouble_f128(func)		\
+  weak_alias (__f ## func ## l, f32 ## func ## f128)
+# define libm_alias_double_ldouble_f128(func)		\
+  weak_alias (__d ## func ## l, f32x ## func ## f128)	\
+  weak_alias (__d ## func ## l, f64 ## func ## f128)
+#else
+# define libm_alias_float_ldouble_f128(func)
+# define libm_alias_double_ldouble_f128(func)
+#endif
+
+#if __HAVE_FLOAT64X_LONG_DOUBLE
+# define libm_alias_float_ldouble_f64x(func)		\
+  weak_alias (__f ## func ## l, f32 ## func ## f64x)
+# define libm_alias_double_ldouble_f64x(func)		\
+  weak_alias (__d ## func ## l, f32x ## func ## f64x)	\
+  weak_alias (__d ## func ## l, f64 ## func ## f64x)
+#else
+# define libm_alias_float_ldouble_f64x(func)
+# define libm_alias_double_ldouble_f64x(func)
+#endif
+
+#define libm_alias_float_ldouble(func)		\
+  weak_alias (__f ## func ## l, f ## func ## l) \
+  libm_alias_float_ldouble_f128 (func)		\
+  libm_alias_float_ldouble_f64x (func)
+
+#define libm_alias_double_ldouble(func)		\
+  weak_alias (__d ## func ## l, d ## func ## l) \
+  libm_alias_double_ldouble_f128 (func)		\
+  libm_alias_double_ldouble_f64x (func)
+
+#define libm_alias_float64x_float128(func)			\
+  weak_alias (__f64x ## func ## f128, f64x ## func ## f128)
+
+#define libm_alias_float32_float128_main(func)			\
+  weak_alias (__f32 ## func ## f128, f32 ## func ## f128)
+
+#define libm_alias_float64_float128_main(func)			\
+  weak_alias (__f64 ## func ## f128, f64 ## func ## f128)	\
+  weak_alias (__f64 ## func ## f128, f32x ## func ## f128)
+
+#include <math-narrow-alias-float128.h>
+
+/* The following macros declare narrowing-named aliases for a
+   non-narrowing function.  */
+
+#define libm_alias_double_narrow_main(from, to)	\
+  weak_alias (from, f32x ## to ## f64)
+
+#ifdef NO_LONG_DOUBLE
+# define libm_alias_double_narrow(from, to)	\
+  libm_alias_double_narrow_main (from, to)	\
+  weak_alias (from, d ## to ## l)
+#else
+# define libm_alias_double_narrow(from, to)	\
+  libm_alias_double_narrow_main (from, to)
+#endif
+
+#if __HAVE_FLOAT64X_LONG_DOUBLE && __HAVE_FLOAT128 && !__HAVE_DISTINCT_FLOAT128
+# define libm_alias_ldouble_narrow(from, to)	\
+  weak_alias (from ## l, f64x ## to ## f128)
+#else
+# define libm_alias_ldouble_narrow(from, to)
+#endif
+
+#if __HAVE_DISTINCT_FLOAT128 && __HAVE_FLOAT64X && !__HAVE_FLOAT64X_LONG_DOUBLE
+# define libm_alias_float128_narrow(from, to)	\
+  weak_alias (from ## f128, f64x ## to ## f128)
+#else
+# define libm_alias_float128_narrow(from, to)
+#endif
+
+#endif /* math-narrow-alias.h.  */
diff --git a/sysdeps/generic/math-type-macros-double.h b/sysdeps/generic/math-type-macros-double.h
index 7abab18af3..8d2d8362cc 100644
--- a/sysdeps/generic/math-type-macros-double.h
+++ b/sysdeps/generic/math-type-macros-double.h
@@ -38,6 +38,11 @@ 
 # define declare_mgen_alias_r(from, to) libm_alias_double_r (from, to, _r)
 #endif
 
+#ifndef declare_mgen_alias_narrow
+# define declare_mgen_alias_narrow(from, to)	\
+  libm_alias_double_narrow (from, to)
+#endif
+
 /* Supply the generic macros.  */
 #include <math-type-macros.h>
 
diff --git a/sysdeps/generic/math-type-macros-float.h b/sysdeps/generic/math-type-macros-float.h
index e0a6a51492..fb84d62909 100644
--- a/sysdeps/generic/math-type-macros-float.h
+++ b/sysdeps/generic/math-type-macros-float.h
@@ -41,6 +41,10 @@ 
 # define declare_mgen_alias_r(from, to) libm_alias_float_r (from, to, _r)
 #endif
 
+#ifndef declare_mgen_alias_narrow
+# define declare_mgen_alias_narrow(from, to)
+#endif
+
 /* Supply the generic macros.  */
 #include <math-type-macros.h>
 
diff --git a/sysdeps/generic/math-type-macros-float128.h b/sysdeps/generic/math-type-macros-float128.h
index 5cdce15a4e..5c190606f5 100644
--- a/sysdeps/generic/math-type-macros-float128.h
+++ b/sysdeps/generic/math-type-macros-float128.h
@@ -40,6 +40,11 @@ 
 # define declare_mgen_alias_r(from, to) libm_alias_float128_r (from, to, _r)
 #endif
 
+#ifndef declare_mgen_alias_narrow
+# define declare_mgen_alias_narrow(from, to)	\
+  libm_alias_float128_narrow (from, to)
+#endif
+
 /* Supply the generic macros.  */
 #include <math-type-macros.h>
 
diff --git a/sysdeps/generic/math-type-macros-ldouble.h b/sysdeps/generic/math-type-macros-ldouble.h
index 2372195ef1..a2f282500e 100644
--- a/sysdeps/generic/math-type-macros-ldouble.h
+++ b/sysdeps/generic/math-type-macros-ldouble.h
@@ -38,6 +38,11 @@ 
 # define declare_mgen_alias_r(from, to) libm_alias_ldouble_r (from, to, _r)
 #endif
 
+#ifndef declare_mgen_alias_narrow
+# define declare_mgen_alias_narrow(from, to)	\
+  libm_alias_ldouble_narrow (from, to)
+#endif
+
 /* Supply the generic macros.  */
 #include <math-type-macros.h>
 
diff --git a/sysdeps/generic/math-type-macros.h b/sysdeps/generic/math-type-macros.h
index 007b14449d..188e39bc1f 100644
--- a/sysdeps/generic/math-type-macros.h
+++ b/sysdeps/generic/math-type-macros.h
@@ -42,6 +42,10 @@ 
       This exposes the appropriate symbol(s) for a
       function f_r of type FLOAT.
 
+  declare_mgen_alias_narrow(from,to)
+      This exposes the appropriate symbol(s) for narrowing aliases of a
+      function f of type FLOAT.
+
   SET_NAN_PAYLOAD(flt, mant)
       Set the NaN payload bits of the variable FLT of type FLOAT to
       the mantissa MANT.  */
@@ -70,6 +74,9 @@ 
 #ifndef declare_mgen_alias_r
 # error "declare_mgen_alias_r must be defined."
 #endif
+#ifndef declare_mgen_alias_narrow
+# error "declare_mgen_alias_narrow must be defined."
+#endif
 #ifndef SET_NAN_PAYLOAD
 # error "SET_NAN_PAYLOAD must be defined."
 #endif
diff --git a/sysdeps/i386/fpu/w_sqrt.c b/sysdeps/i386/fpu/w_sqrt.c
index 8bef04e68a..644c7c870c 100644
--- a/sysdeps/i386/fpu/w_sqrt.c
+++ b/sysdeps/i386/fpu/w_sqrt.c
@@ -2,7 +2,9 @@ 
    most internal uses in glibc, but not for sqrt itself.  */
 #define NO_MATH_REDIRECT
 #define __ieee754_sqrt __avoid_ieee754_sqrt
+#define f32xsqrtf64 __hide_f32xsqrtf64
 #include <math.h>
+#undef f32xsqrtf64
 #include <math_private.h>
 #undef __ieee754_sqrt
 extern double __ieee754_sqrt (double);
diff --git a/sysdeps/i386/fpu/w_sqrt_compat.c b/sysdeps/i386/fpu/w_sqrt_compat.c
index dd485f4b88..f5d3cf91d1 100644
--- a/sysdeps/i386/fpu/w_sqrt_compat.c
+++ b/sysdeps/i386/fpu/w_sqrt_compat.c
@@ -2,7 +2,9 @@ 
    most internal uses in glibc, but not for sqrt itself.  */
 #define NO_MATH_REDIRECT
 #define __ieee754_sqrt __avoid_ieee754_sqrt
+#define f32xsqrtf64 __hide_f32xsqrtf64
 #include <math.h>
+#undef f32xsqrtf64
 #include <math_private.h>
 #undef __ieee754_sqrt
 extern double __ieee754_sqrt (double);
diff --git a/sysdeps/ia64/fpu/e_sqrt.S b/sysdeps/ia64/fpu/e_sqrt.S
index 750183772b..3b9c17059e 100644
--- a/sysdeps/ia64/fpu/e_sqrt.S
+++ b/sysdeps/ia64/fpu/e_sqrt.S
@@ -252,6 +252,7 @@  GLOBAL_IEEE754_ENTRY(sqrt)
 // END DOUBLE PRECISION MINIMUM LATENCY SQUARE ROOT ALGORITHM
 GLOBAL_IEEE754_END(sqrt)
 libm_alias_double_other (__sqrt, sqrt)
+libm_alias_double_narrow (__sqrt, sqrt)
 
 // Stack operations when calling error support.
 //       (1)               (2)                          (3) (call)              (4)
diff --git a/sysdeps/ia64/fpu/libm-symbols.h b/sysdeps/ia64/fpu/libm-symbols.h
index 4a551c9f17..56503cfe4e 100644
--- a/sysdeps/ia64/fpu/libm-symbols.h
+++ b/sysdeps/ia64/fpu/libm-symbols.h
@@ -5,6 +5,7 @@ 
 # include <libm-alias-float.h>
 # include <libm-alias-double.h>
 # include <libm-alias-ldouble.h>
+# include <math-narrow-alias.h>
 
 /* Support for compatible assembler handling.  */
 
diff --git a/sysdeps/ieee754/dbl-64/s_f32xsqrtf64.c b/sysdeps/ieee754/dbl-64/s_f32xsqrtf64.c
new file mode 100644
index 0000000000..9af76a25b0
--- /dev/null
+++ b/sysdeps/ieee754/dbl-64/s_f32xsqrtf64.c
@@ -0,0 +1 @@ 
+/* Defined as an alias of sqrt.  */
diff --git a/sysdeps/ieee754/dbl-64/s_fsqrt.c b/sysdeps/ieee754/dbl-64/s_fsqrt.c
new file mode 100644
index 0000000000..0354ba9fbf
--- /dev/null
+++ b/sysdeps/ieee754/dbl-64/s_fsqrt.c
@@ -0,0 +1,34 @@ 
+/* Square root of double value, narrowing the result to float.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#define f32sqrtf64 __hide_f32sqrtf64
+#define f32sqrtf32x __hide_f32sqrtf32x
+#define fsqrtl __hide_fsqrtl
+#include <math.h>
+#undef f32sqrtf64
+#undef f32sqrtf32x
+#undef fsqrtl
+
+#include <math-narrow.h>
+
+float
+__fsqrt (double x)
+{
+  NARROW_SQRT_ROUND_TO_ODD (x, float, union ieee754_double, , mantissa1);
+}
+libm_alias_float_double (sqrt)
diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h
index b6b6d3d5fd..13d1d63baf 100644
--- a/sysdeps/ieee754/float128/float128_private.h
+++ b/sysdeps/ieee754/float128/float128_private.h
@@ -138,6 +138,9 @@ 
 #define libm_alias_float_ldouble(func) libm_alias_float32_float128 (func)
 #undef libm_alias_double_ldouble
 #define libm_alias_double_ldouble(func) libm_alias_float64_float128 (func)
+#undef libm_alias_ldouble_narrow
+#define libm_alias_ldouble_narrow(from, to)	\
+  libm_alias_float128_narrow (from, to)
 
 #include <math-use-builtins.h>
 #undef USE_NEARBYINTL_BUILTIN
@@ -284,6 +287,8 @@ 
 #define __ddivl __f64divf128
 #define __fmull __f32mulf128
 #define __dmull __f64mulf128
+#define __fsqrtl __f32sqrtf128
+#define __dsqrtl __f64sqrtf128
 #define __fsubl __f32subf128
 #define __dsubl __f64subf128
 
diff --git a/sysdeps/ieee754/float128/s_f32sqrtf128.c b/sysdeps/ieee754/float128/s_f32sqrtf128.c
new file mode 100644
index 0000000000..74e91abd4d
--- /dev/null
+++ b/sysdeps/ieee754/float128/s_f32sqrtf128.c
@@ -0,0 +1,6 @@ 
+#define f32sqrtf64x __hide_f32sqrtf64x
+#define f32sqrtf128 __hide_f32sqrtf128
+#include <float128_private.h>
+#undef f32sqrtf64x
+#undef f32sqrtf128
+#include "../ldbl-128/s_fsqrtl.c"
diff --git a/sysdeps/ieee754/float128/s_f64sqrtf128.c b/sysdeps/ieee754/float128/s_f64sqrtf128.c
new file mode 100644
index 0000000000..8373879d42
--- /dev/null
+++ b/sysdeps/ieee754/float128/s_f64sqrtf128.c
@@ -0,0 +1,10 @@ 
+#define f32xsqrtf64x __hide_f32xsqrtf64x
+#define f32xsqrtf128 __hide_f32xsqrtf128
+#define f64sqrtf64x __hide_f64sqrtf64x
+#define f64sqrtf128 __hide_f64sqrtf128
+#include <float128_private.h>
+#undef f32xsqrtf64x
+#undef f32xsqrtf128
+#undef f64sqrtf64x
+#undef f64sqrtf128
+#include "../ldbl-128/s_dsqrtl.c"
diff --git a/sysdeps/ieee754/float128/s_f64xsqrtf128.c b/sysdeps/ieee754/float128/s_f64xsqrtf128.c
new file mode 100644
index 0000000000..383f92a94e
--- /dev/null
+++ b/sysdeps/ieee754/float128/s_f64xsqrtf128.c
@@ -0,0 +1,2 @@ 
+#include <float128_private.h>
+#include "../ldbl-128/s_f64xsqrtf128.c"
diff --git a/sysdeps/ieee754/ldbl-128/s_dsqrtl.c b/sysdeps/ieee754/ldbl-128/s_dsqrtl.c
new file mode 100644
index 0000000000..b0d0162467
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128/s_dsqrtl.c
@@ -0,0 +1,37 @@ 
+/* Square root of long double (ldbl-128) value, narrowing the result to double.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#define f32xsqrtf64x __hide_f32xsqrtf64x
+#define f32xsqrtf128 __hide_f32xsqrtf128
+#define f64sqrtf64x __hide_f64sqrtf64x
+#define f64sqrtf128 __hide_f64sqrtf128
+#include <math.h>
+#undef f32xsqrtf64x
+#undef f32xsqrtf128
+#undef f64sqrtf64x
+#undef f64sqrtf128
+
+#include <math-narrow.h>
+
+double
+__dsqrtl (_Float128 x)
+{
+  NARROW_SQRT_ROUND_TO_ODD (x, double, union ieee854_long_double, l,
+			    mantissa3);
+}
+libm_alias_double_ldouble (sqrt)
diff --git a/sysdeps/ieee754/ldbl-128/s_f64xsqrtf128.c b/sysdeps/ieee754/ldbl-128/s_f64xsqrtf128.c
new file mode 100644
index 0000000000..2f1898d48c
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128/s_f64xsqrtf128.c
@@ -0,0 +1,38 @@ 
+/* Square root of _Float128 value, converting the result to _Float64x.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math-narrow.h>
+
+/* math_ldbl.h defines _Float128 to long double for this directory,
+   but when they are different, this function must be defined with
+   _Float128 arguments to avoid defining an alias with an incompatible
+   type.  */
+#undef _Float128
+
+#if __HAVE_FLOAT64X_LONG_DOUBLE && __HAVE_DISTINCT_FLOAT128
+_Float64x
+__f64xsqrtf128 (_Float128 x)
+{
+  NARROW_SQRT_ROUND_TO_ODD (x, _Float64x, union ieee854_long_double, l,
+			    mantissa3);
+}
+libm_alias_float64x_float128 (sqrt)
+#else
+/* Defined as an alias of sqrtl.  */
+#endif
diff --git a/sysdeps/ieee754/ldbl-128/s_fsqrtl.c b/sysdeps/ieee754/ldbl-128/s_fsqrtl.c
new file mode 100644
index 0000000000..95afe7b7ad
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128/s_fsqrtl.c
@@ -0,0 +1,33 @@ 
+/* Square root of long double (ldbl-128) value, narrowing the result to float.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#define f32sqrtf64x __hide_f32sqrtf64x
+#define f32sqrtf128 __hide_f32sqrtf128
+#include <math.h>
+#undef f32sqrtf64x
+#undef f32sqrtf128
+
+#include <math-narrow.h>
+
+float
+__fsqrtl (_Float128 x)
+{
+  NARROW_SQRT_ROUND_TO_ODD (x, float, union ieee854_long_double, l,
+			    mantissa3);
+}
+libm_alias_float_ldouble (sqrt)
diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/Versions b/sysdeps/ieee754/ldbl-128ibm-compat/Versions
index 07e6a5b08a..885ffb977f 100644
--- a/sysdeps/ieee754/ldbl-128ibm-compat/Versions
+++ b/sysdeps/ieee754/ldbl-128ibm-compat/Versions
@@ -123,6 +123,10 @@  libm {
     __y1ieee128;
     __ynieee128;
   }
+  GLIBC_2.35 {
+    __f32sqrtieee128;
+    __f64sqrtieee128;
+  }
 }
 libc {
   LDBL_IBM128_VERSION {
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_dsqrtl.c b/sysdeps/ieee754/ldbl-128ibm/s_dsqrtl.c
new file mode 100644
index 0000000000..786ea7001b
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm/s_dsqrtl.c
@@ -0,0 +1,28 @@ 
+/* Square root of long double (ldbl-128ibm) value, narrowing the result to
+   double.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math-narrow.h>
+
+double
+__dsqrtl (long double x)
+{
+  NARROW_SQRT_TRIVIAL (x, double, l);
+}
+libm_alias_double_ldouble (sqrt)
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_fsqrtl.c b/sysdeps/ieee754/ldbl-128ibm/s_fsqrtl.c
new file mode 100644
index 0000000000..abfc0d69fe
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm/s_fsqrtl.c
@@ -0,0 +1,28 @@ 
+/* Square root of long double (ldbl-128ibm) value, narrowing the result to
+   float.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math-narrow.h>
+
+float
+__fsqrtl (long double x)
+{
+  NARROW_SQRT_TRIVIAL (x, float, l);
+}
+libm_alias_float_ldouble (sqrt)
diff --git a/sysdeps/ieee754/ldbl-96/s_dsqrtl.c b/sysdeps/ieee754/ldbl-96/s_dsqrtl.c
new file mode 100644
index 0000000000..8bfc9624c2
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-96/s_dsqrtl.c
@@ -0,0 +1,33 @@ 
+/* Square root of long double (ldbl-96) value, narrowing the result to double.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#define f32xsqrtf64x __hide_f32xsqrtf64x
+#define f64sqrtf64x __hide_f64sqrtf64x
+#include <math.h>
+#undef f32xsqrtf64x
+#undef f64sqrtf64x
+
+#include <math-narrow.h>
+
+double
+__dsqrtl (long double x)
+{
+  NARROW_SQRT_ROUND_TO_ODD (x, double, union ieee854_long_double, l,
+			    mantissa1);
+}
+libm_alias_double_ldouble (sqrt)
diff --git a/sysdeps/ieee754/ldbl-96/s_fsqrtl.c b/sysdeps/ieee754/ldbl-96/s_fsqrtl.c
new file mode 100644
index 0000000000..026add5d03
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-96/s_fsqrtl.c
@@ -0,0 +1,31 @@ 
+/* Square root of long double (ldbl-96) value, narrowing the result to float.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#define f32sqrtf64x __hide_f32sqrtf64x
+#include <math.h>
+#undef f32sqrtf64x
+
+#include <math-narrow.h>
+
+float
+__fsqrtl (long double x)
+{
+  NARROW_SQRT_ROUND_TO_ODD (x, float, union ieee854_long_double, l,
+			    mantissa1);
+}
+libm_alias_float_ldouble (sqrt)
diff --git a/sysdeps/ieee754/ldbl-opt/Makefile b/sysdeps/ieee754/ldbl-opt/Makefile
index 4e41a27e80..dff53cc0d8 100644
--- a/sysdeps/ieee754/ldbl-opt/Makefile
+++ b/sysdeps/ieee754/ldbl-opt/Makefile
@@ -45,7 +45,7 @@  libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
 		 nextup nextdown totalorder totalordermag getpayload \
 		 canonicalize setpayload setpayloadsig llogb fmaxmag fminmag \
 		 roundeven fromfp ufromfp fromfpx ufromfpx fadd dadd \
-		 fdiv ddiv fmul dmul fsub dsub
+		 fdiv ddiv fmul dmul fsqrt dsqrt fsub dsub
 libnldbl-routines = $(libnldbl-calls:%=nldbl-%)
 libnldbl-inhibit-o = $(object-suffixes)
 libnldbl-static-only-routines = $(libnldbl-routines)
@@ -90,6 +90,7 @@  CFLAGS-nldbl-ctanh.c = -fno-builtin-ctanhl
 CFLAGS-nldbl-dadd.c = -fno-builtin-daddl
 CFLAGS-nldbl-ddiv.c = -fno-builtin-ddivl
 CFLAGS-nldbl-dmul.c = -fno-builtin-dmull
+CFLAGS-nldbl-dsqrt.c = -fno-builtin-dsqrtl
 CFLAGS-nldbl-dsub.c = -fno-builtin-dsubl
 CFLAGS-nldbl-erf.c = -fno-builtin-erfl
 CFLAGS-nldbl-erfc.c = -fno-builtin-erfcl
@@ -113,6 +114,7 @@  CFLAGS-nldbl-fmul.c = -fno-builtin-fmull
 CFLAGS-nldbl-frexp.c = -fno-builtin-frexpl
 CFLAGS-nldbl-fromfp.c = -fno-builtin-fromfpl
 CFLAGS-nldbl-fromfpx.c = -fno-builtin-fromfpxl
+CFLAGS-nldbl-fsqrt.c = -fno-builtin-fsqrtl
 CFLAGS-nldbl-fsub.c = -fno-builtin-fsubl
 CFLAGS-nldbl-gamma.c = -fno-builtin-gammal
 CFLAGS-nldbl-getpayload.c = -fno-builtin-getpayloadl
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-dsqrt.c b/sysdeps/ieee754/ldbl-opt/nldbl-dsqrt.c
new file mode 100644
index 0000000000..1d131f083d
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/nldbl-dsqrt.c
@@ -0,0 +1,28 @@ 
+/* Compatibility routine for IEEE double as long double for dsqrt.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#define dsqrtl __hide_dsqrtl
+#include "nldbl-compat.h"
+#undef dsqrtl
+
+double
+attribute_hidden
+dsqrtl (double x)
+{
+  return sqrt (x);
+}
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-fsqrt.c b/sysdeps/ieee754/ldbl-opt/nldbl-fsqrt.c
new file mode 100644
index 0000000000..bcdf1aa556
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/nldbl-fsqrt.c
@@ -0,0 +1,28 @@ 
+/* Compatibility routine for IEEE double as long double for fsqrt.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#define fsqrtl __hide_fsqrtl
+#include "nldbl-compat.h"
+#undef fsqrtl
+
+float
+attribute_hidden
+fsqrtl (double x)
+{
+  return fsqrt (x);
+}
diff --git a/sysdeps/ieee754/soft-fp/s_dsqrtl.c b/sysdeps/ieee754/soft-fp/s_dsqrtl.c
new file mode 100644
index 0000000000..85ea8538a5
--- /dev/null
+++ b/sysdeps/ieee754/soft-fp/s_dsqrtl.c
@@ -0,0 +1,67 @@ 
+/* Square root of long double (ldbl-128) value, narrowing the result to
+   double, using soft-fp.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#define f32xsqrtf64x __hide_f32xsqrtf64x
+#define f32xsqrtf128 __hide_f32xsqrtf128
+#define f64sqrtf64x __hide_f64sqrtf64x
+#define f64sqrtf128 __hide_f64sqrtf128
+#include <math.h>
+#undef f32xsqrtf64x
+#undef f32xsqrtf128
+#undef f64sqrtf64x
+#undef f64sqrtf128
+
+#include <math-narrow.h>
+#include <libc-diag.h>
+
+/* Some components of the result's significand and exponent are not
+   set in cases where they are not used in packing, but the compiler
+   does not see that they are set in all cases where they are used,
+   resulting in warnings that they may be used uninitialized.  */
+DIAG_PUSH_NEEDS_COMMENT;
+DIAG_IGNORE_NEEDS_COMMENT (7, "-Wmaybe-uninitialized");
+#include <soft-fp.h>
+#include <double.h>
+#include <quad.h>
+
+double
+__dsqrtl (_Float128 x)
+{
+  FP_DECL_EX;
+  FP_DECL_Q (X);
+  FP_DECL_Q (R);
+  FP_DECL_D (RN);
+  double ret;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q (X, x);
+  FP_SQRT_Q (R, X);
+#if _FP_W_TYPE_SIZE < 64
+  FP_TRUNC_COOKED (D, Q, 2, 4, RN, R);
+#else
+  FP_TRUNC_COOKED (D, Q, 1, 2, RN, R);
+#endif
+  FP_PACK_D (ret, RN);
+  FP_HANDLE_EXCEPTIONS;
+  CHECK_NARROW_SQRT (ret, x);
+  return ret;
+}
+DIAG_POP_NEEDS_COMMENT;
+
+libm_alias_double_ldouble (sqrt)
diff --git a/sysdeps/ieee754/soft-fp/s_fsqrt.c b/sysdeps/ieee754/soft-fp/s_fsqrt.c
new file mode 100644
index 0000000000..b6f7c4e962
--- /dev/null
+++ b/sysdeps/ieee754/soft-fp/s_fsqrt.c
@@ -0,0 +1,54 @@ 
+/* Square root of double value, narrowing the result to float, using soft-fp.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#define f32sqrtf64 __hide_f32sqrtf64
+#define f32sqrtf32x __hide_f32sqrtf32x
+#define fsqrtl __hide_fsqrtl
+#include <math.h>
+#undef f32sqrtf64
+#undef f32sqrtf32x
+#undef fsqrtl
+
+#include <math-narrow.h>
+#include <soft-fp.h>
+#include <single.h>
+#include <double.h>
+
+float
+__fsqrt (double x)
+{
+  FP_DECL_EX;
+  FP_DECL_D (X);
+  FP_DECL_D (R);
+  FP_DECL_S (RN);
+  float ret;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_D (X, x);
+  FP_SQRT_D (R, X);
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+  FP_TRUNC_COOKED (S, D, 1, 2, RN, R);
+#else
+  FP_TRUNC_COOKED (S, D, 1, 1, RN, R);
+#endif
+  FP_PACK_S (ret, RN);
+  FP_HANDLE_EXCEPTIONS;
+  CHECK_NARROW_SQRT (ret, x);
+  return ret;
+}
+libm_alias_float_double (sqrt)
diff --git a/sysdeps/ieee754/soft-fp/s_fsqrtl.c b/sysdeps/ieee754/soft-fp/s_fsqrtl.c
new file mode 100644
index 0000000000..618e734744
--- /dev/null
+++ b/sysdeps/ieee754/soft-fp/s_fsqrtl.c
@@ -0,0 +1,53 @@ 
+/* Square root of long double (ldbl-128) value, narrowing the result to
+   float, using soft-fp.
+   Copyright (C) 2021 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
+   <https://www.gnu.org/licenses/>.  */
+
+#define f32sqrtf64x __hide_f32sqrtf64x
+#define f32sqrtf128 __hide_f32sqrtf128
+#include <math.h>
+#undef f32sqrtf64x
+#undef f32sqrtf128
+
+#include <math-narrow.h>
+#include <soft-fp.h>
+#include <single.h>
+#include <quad.h>
+
+float
+__fsqrtl (_Float128 x)
+{
+  FP_DECL_EX;
+  FP_DECL_Q (X);
+  FP_DECL_Q (R);
+  FP_DECL_S (RN);
+  float ret;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q (X, x);
+  FP_SQRT_Q (R, X);
+#if _FP_W_TYPE_SIZE < 64
+  FP_TRUNC_COOKED (S, Q, 1, 4, RN, R);
+#else
+  FP_TRUNC_COOKED (S, Q, 1, 2, RN, R);
+#endif
+  FP_PACK_S (ret, RN);
+  FP_HANDLE_EXCEPTIONS;
+  CHECK_NARROW_SQRT (ret, x);
+  return ret;
+}
+libm_alias_float_ldouble (sqrt)
diff --git a/sysdeps/mach/hurd/i386/libm.abilist b/sysdeps/mach/hurd/i386/libm.abilist
index bb077b9030..1a107a67dc 100644
--- a/sysdeps/mach/hurd/i386/libm.abilist
+++ b/sysdeps/mach/hurd/i386/libm.abilist
@@ -1089,3 +1089,16 @@  GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagf64x F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/powerpc/fpu/libm-test-ulps b/sysdeps/powerpc/fpu/libm-test-ulps
index 513c4343ee..a605aebfc5 100644
--- a/sysdeps/powerpc/fpu/libm-test-ulps
+++ b/sysdeps/powerpc/fpu/libm-test-ulps
@@ -1623,6 +1623,9 @@  ldouble: 1
 Function: "sqrt_downward":
 ldouble: 1
 
+Function: "sqrt_ldouble":
+double: 1
+
 Function: "sqrt_towardzero":
 ldouble: 1
 
diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-macros.h b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-macros.h
index b03870070f..abab686aa9 100644
--- a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-macros.h
+++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc-macros.h
@@ -32,6 +32,7 @@ 
 #undef declare_mgen_finite_alias
 #undef declare_mgen_alias
 #undef declare_mgen_alias_r
+#undef declare_mgen_alias_narrow
 
 #define libm_alias_finite(from, to)
 #define libm_alias_float128_r(from, to, r)
@@ -40,6 +41,7 @@ 
 #define declare_mgen_finite_alias(from, to)
 #define declare_mgen_alias(from, to)
 #define declare_mgen_alias_r(from, to)
+#define declare_mgen_alias_narrow(from, to)
 
 /*  Likewise, disable hidden symbol support.  This is not needed
     for the implementation objects as the redirects already give
diff --git a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc.h b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc.h
index 001cbf70b9..392c66b63d 100644
--- a/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc.h
+++ b/sysdeps/powerpc/powerpc64/le/fpu/multiarch/float128-ifunc.h
@@ -27,7 +27,9 @@ 
 
 /* Include the real math.h to avoid optimizations caused by include/math.h
    (e.x fabsf128 prototype is masked by an inline definition).*/
+#define f64xsqrtf128 __hide_f64xsqrtf128
 #include <math/math.h>
+#undef f64xsqrtf128
 #include <math_private.h>
 #include <complex.h>
 #include <first-versions.h>
@@ -36,6 +38,7 @@ 
 
 #include <libm-alias-float128.h>
 #include <libm-alias-finite.h>
+#include <math-narrow-alias.h>
 
 /* _F128_IFUNC2(func, from, r)
       Generate an ifunc symbol func ## r from the symbols
@@ -149,6 +152,9 @@ 
 /* scalbnf128 is an alias of ldexpf128.  */
 #define DECL_ALIAS_s_ldexp(f) MAKE_IFUNCP_R (f,) MAKE_IFUNCP_WRAP_R (wrap_, scalbn,)
 
+/* f64xsqrtf128 is an alias of sqrtf128.  */
+#define DECL_ALIAS_w_sqrt(f) MAKE_IFUNCP_R (f,) libm_alias_float128_narrow (__sqrt, sqrt)
+
 /* Declare an IFUNC for a symbol which only exists
    to provide long double == ieee128 ABI.  */
 #define DECL_LDOUBLE_ALIAS(func, RTYPE, ARGS) \
diff --git a/sysdeps/unix/sysv/linux/aarch64/libm.abilist b/sysdeps/unix/sysv/linux/aarch64/libm.abilist
index 5362c24e4c..74f203575f 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libm.abilist
@@ -1054,3 +1054,16 @@  GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagf64x F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/alpha/libm.abilist b/sysdeps/unix/sysv/linux/alpha/libm.abilist
index 650d10ec8e..e3c619e77a 100644
--- a/sysdeps/unix/sysv/linux/alpha/libm.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libm.abilist
@@ -1111,6 +1111,19 @@  GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagf64x F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
 GLIBC_2.4 __clog10l F
 GLIBC_2.4 __finitel F
 GLIBC_2.4 __fpclassifyl F
diff --git a/sysdeps/unix/sysv/linux/arc/libm.abilist b/sysdeps/unix/sysv/linux/arc/libm.abilist
index 4338563657..cedb2ffcc4 100644
--- a/sysdeps/unix/sysv/linux/arc/libm.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libm.abilist
@@ -697,3 +697,9 @@  GLIBC_2.32 ynf32 F
 GLIBC_2.32 ynf32x F
 GLIBC_2.32 ynf64 F
 GLIBC_2.32 ynl F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libm.abilist b/sysdeps/unix/sysv/linux/arm/be/libm.abilist
index 6914b58d76..97f328dbbd 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libm.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libm.abilist
@@ -471,6 +471,12 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
 GLIBC_2.4 _LIB_VERSION D 0x4
 GLIBC_2.4 __clog10 F
 GLIBC_2.4 __clog10f F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libm.abilist b/sysdeps/unix/sysv/linux/arm/le/libm.abilist
index 6914b58d76..97f328dbbd 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libm.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libm.abilist
@@ -471,6 +471,12 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
 GLIBC_2.4 _LIB_VERSION D 0x4
 GLIBC_2.4 __clog10 F
 GLIBC_2.4 __clog10f F
diff --git a/sysdeps/unix/sysv/linux/csky/libm.abilist b/sysdeps/unix/sysv/linux/csky/libm.abilist
index 88cdf00342..88761113e6 100644
--- a/sysdeps/unix/sysv/linux/csky/libm.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libm.abilist
@@ -763,3 +763,9 @@  GLIBC_2.31 totalordermagf32 F
 GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/hppa/libm.abilist b/sysdeps/unix/sysv/linux/hppa/libm.abilist
index 6ac2295b05..c32ff03983 100644
--- a/sysdeps/unix/sysv/linux/hppa/libm.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libm.abilist
@@ -782,4 +782,10 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
 GLIBC_2.4 exp2l F
diff --git a/sysdeps/unix/sysv/linux/i386/libm.abilist b/sysdeps/unix/sysv/linux/i386/libm.abilist
index 335b5e7aa2..2a2b290dc9 100644
--- a/sysdeps/unix/sysv/linux/i386/libm.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libm.abilist
@@ -1096,3 +1096,16 @@  GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagf64x F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/ia64/libm.abilist b/sysdeps/unix/sysv/linux/ia64/libm.abilist
index ec82b83e6f..47511731f8 100644
--- a/sysdeps/unix/sysv/linux/ia64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libm.abilist
@@ -1026,3 +1026,16 @@  GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagf64x F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
index 6914b58d76..97f328dbbd 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
@@ -471,6 +471,12 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
 GLIBC_2.4 _LIB_VERSION D 0x4
 GLIBC_2.4 __clog10 F
 GLIBC_2.4 __clog10f F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist
index c60fdc6298..6925a90820 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist
@@ -822,3 +822,9 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist
index adea0fe4c0..65ade6d272 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist
@@ -783,3 +783,9 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist
index adea0fe4c0..65ade6d272 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist
@@ -783,3 +783,9 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
index 272969a26f..f53f8d86c5 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
@@ -782,4 +782,10 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
 GLIBC_2.4 exp2l F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
index dd0dc6689c..1abb41514c 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
@@ -1054,3 +1054,16 @@  GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagf64x F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/nios2/libm.abilist b/sysdeps/unix/sysv/linux/nios2/libm.abilist
index 4941deefa6..8cac2ab005 100644
--- a/sysdeps/unix/sysv/linux/nios2/libm.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libm.abilist
@@ -783,3 +783,9 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
index fc2d142bd5..6c70bd6de3 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
@@ -828,6 +828,12 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
 GLIBC_2.4 __clog10l F
 GLIBC_2.4 __finitel F
 GLIBC_2.4 __fpclassifyl F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
index e6feaf7ec7..dd7f2c30c9 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
@@ -827,6 +827,12 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
 GLIBC_2.4 __clog10l F
 GLIBC_2.4 __finitel F
 GLIBC_2.4 __fpclassifyl F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist
index 972c9bc597..aac3ff683f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist
@@ -821,6 +821,12 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
 GLIBC_2.4 __clog10l F
 GLIBC_2.4 __finitel F
 GLIBC_2.4 __fpclassifyl F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist
index 8266bc32f4..7fe920d4d4 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist
@@ -1214,3 +1214,18 @@  GLIBC_2.32 __y0ieee128 F
 GLIBC_2.32 __y1ieee128 F
 GLIBC_2.32 __ynieee128 F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 __f32sqrtieee128 F
+GLIBC_2.35 __f64sqrtieee128 F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libm.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libm.abilist
index c701b07a9a..a8638faa6f 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libm.abilist
@@ -938,3 +938,16 @@  GLIBC_2.33 ynf32x F
 GLIBC_2.33 ynf64 F
 GLIBC_2.33 ynf64x F
 GLIBC_2.33 ynl F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libm.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libm.abilist
index 90d9073188..dc682a7c52 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libm.abilist
@@ -1035,3 +1035,16 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagf64x F
 GLIBC_2.31 totalordermagl F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
index 321810d5a4..5d2abaa2db 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
@@ -1055,6 +1055,19 @@  GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagf64x F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
 GLIBC_2.4 __clog10l F
 GLIBC_2.4 __finitel F
 GLIBC_2.4 __fpclassifyl F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
index 451a860a83..f41c9f7a29 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
@@ -1055,6 +1055,19 @@  GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagf64x F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
 GLIBC_2.4 __clog10l F
 GLIBC_2.4 __finitel F
 GLIBC_2.4 __fpclassifyl F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libm.abilist b/sysdeps/unix/sysv/linux/sh/be/libm.abilist
index a5fb514eae..6a379eced4 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libm.abilist
@@ -782,4 +782,10 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
 GLIBC_2.4 exp2l F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libm.abilist b/sysdeps/unix/sysv/linux/sh/le/libm.abilist
index a5fb514eae..6a379eced4 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libm.abilist
@@ -782,4 +782,10 @@  GLIBC_2.31 totalordermagf32x F
 GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
 GLIBC_2.4 exp2l F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
index d81e8a726b..e06572a3f9 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
@@ -1062,6 +1062,19 @@  GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagf64x F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
 GLIBC_2.4 __clog10l F
 GLIBC_2.4 __finitel F
 GLIBC_2.4 __fpclassifyl F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
index 3d12376d33..6d1e4ae31a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
@@ -1054,3 +1054,16 @@  GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagf64x F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
index b6a088ca64..7185df2a42 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
@@ -1087,3 +1087,16 @@  GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagf64x F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
index dfb5a7fa79..9b29d72d2e 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
@@ -1087,3 +1087,16 @@  GLIBC_2.31 totalordermagf64 F
 GLIBC_2.31 totalordermagf64x F
 GLIBC_2.31 totalordermagl F
 GLIBC_2.32 exp10f F
+GLIBC_2.35 dsqrtl F
+GLIBC_2.35 f32sqrtf128 F
+GLIBC_2.35 f32sqrtf32x F
+GLIBC_2.35 f32sqrtf64 F
+GLIBC_2.35 f32sqrtf64x F
+GLIBC_2.35 f32xsqrtf128 F
+GLIBC_2.35 f32xsqrtf64 F
+GLIBC_2.35 f32xsqrtf64x F
+GLIBC_2.35 f64sqrtf128 F
+GLIBC_2.35 f64sqrtf64x F
+GLIBC_2.35 f64xsqrtf128 F
+GLIBC_2.35 fsqrt F
+GLIBC_2.35 fsqrtl F