[RFC] libstdc++, v2: Partial library support for std::float{16,32,64,128}_t

Message ID Y0vayeXfX4DsqW6g@tucnak
State Unresolved
Headers
Series [RFC] libstdc++, v2: Partial library support for std::float{16,32,64,128}_t |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Jakub Jelinek Oct. 16, 2022, 10:20 a.m. UTC
  Hi!

As the __bf16 support is now in at least on x86_64/i686, I've
updated my patch to cover bfloat16_t as well and implemented almost
everything for <cmath> - the only thing missing I'm aware of is
std::nextafter std::float16_t and std::bfloat16_t overloads (I think
we probably need to implement that out of line somewhere, or inline? - might
need inline asm barriers) and std::nexttoward overloads (those are
intentional, you said there is a LWG issue about that).
If you want to have <cmath> done in a different way, e.g. the patch
groups a lot of different function overloads by the floating point type,
is that ok or do you want to have them one function at a time for all types,
then next?
I could try to handle <complex> too, but am kind of lost there.
The paper dropped the explicit std::complex specializations, can they stay
around as is and should new overloads be added for the
_Float*/__gnu_cxx::__bfloat16_t types?
And I/O etc. support is missing, not sure I'm able to handle that and if it
is e.g. possible to keep that support out of libstdc++.so.6, because what
extended floating point types one has on a particular arch could change over
time (I mean e.g. bfloat16_t support or float16_t support can be added
etc.).

Bootstrapped/regtested on x86_64-linux and i686-linux.

2022-10-15  Jakub Jelinek  <jakub@redhat.com>

	* include/std/stdfloat: New file.
	* include/std/numbers (__glibcxx_numbers): Define and use it
	for __float128 explicit instantiations as well as
	_Float{16,32,64,128} and __gnu_cxx::__bfloat16_t.
	* include/std/atomic (atomic<_Float16>, atomic<_Float32>,
	atomic<_Float64>, atomic<_Float128>, atomic<__gnu_cxx::__bfloat16_t>):
	New explicit instantiations.
	* include/std/type_traits (__is_floating_point_helper<_Float16>,
	__is_floating_point_helper<_Float32>,
	__is_floating_point_helper<_Float64>,
	__is_floating_point_helper<_Float128>,
	__is_floating_point_helper<__gnu_cxx::__bfloat16_t>): Likewise.
	* include/std/limits (__glibcxx_concat3_, __glibcxx_concat3,
	__glibcxx_float_n): Define.
	(numeric_limits<_Float16>, numeric_limits<_Float32>,
	numeric_limits<_Float64>, numeric_limits<_Float128>,
	numeric_limits<__gnu_cxx::__bfloat16_t>): New explicit instantiations.
	* include/bits/std_abs.h (abs): New overloads for
	_Float{16,32,64,128} and __gnu_cxx::__bfloat16_t.
	* include/bits/c++config (_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128): Define
	if long double is IEEE quad.
	(__gnu_cxx::__bfloat16_t): New using.
	* include/c_global/cmath (acos, asin, atan, atan2, ceil, cos, cosh,
	exp, fabs, floor, fmod, frexp, ldexp, log, log10, modf, pow, sin,
	sinh, sqrt, tan, tanh, fpclassify, isfinite, isinf, isnan, isnormal,
	signbit, isgreater, isgreaterequal, isless, islessequal,
	islessgreater, isunordered, acosh, asinh, atanh, cbrt, copysign, erf,
	erfc, exp2, expm1, fdim, fma, fmax, fmin, hypot, ilogb, lgamma,
	llrint, llround, log1p, log2, logb, lrint, lround, nearbyint,
	nextafter, remainder, rint, round, scalbln, scalbn, tgamma, trunc,
	lerp): New overloads with _Float{16,32,64,128} or
	__gnu_cxx::__bfloat16_t types.
	* config/os/gnu-linux/os_defines.h (_GLIBCXX_HAVE_FLOAT128_MATH):
	Define if glibc 2.26 and later implements *f128 APIs.
	* include/ext/type_traits.h (__promote<_Float16>, __promote<_Float32>,
	__promote<_Float64>, __promote<_Float128>,
	__promote<__gnu_cxx::__bfloat16_t>): New specializations.
	* include/Makefile.am (std_headers): Add stdfloat.
	* include/Makefile.in: Regenerated.
	* include/precompiled/stdc++.h: Include stdfloat.
	* testsuite/18_support/headers/stdfloat/types_std.cc: New test.
	* testsuite/18_support/headers/limits/synopsis_cxx23.cc: New test.
	* testsuite/26_numerics/headers/cmath/c99_classification_macros_c++23.cc:
	New test.
	* testsuite/26_numerics/headers/cmath/functions_std_c++23.cc: New test.
	* testsuite/26_numerics/numbers/4.cc: New test.
	* testsuite/29_atomics/atomic_float/requirements_cxx23.cc: New test.



	Jakub
  

Comments

Jonathan Wakely Oct. 17, 2022, 1:07 p.m. UTC | #1
On Sun, 16 Oct 2022 at 11:23, Jakub Jelinek <jakub@redhat.com> wrote:
>
> Hi!
>
> As the __bf16 support is now in at least on x86_64/i686, I've
> updated my patch to cover bfloat16_t as well and implemented almost
> everything for <cmath> - the only thing missing I'm aware of is
> std::nextafter std::float16_t and std::bfloat16_t overloads (I think
> we probably need to implement that out of line somewhere, or inline? - might
> need inline asm barriers) and std::nexttoward overloads (those are
> intentional, you said there is a LWG issue about that).

Yes, that's now https://cplusplus.github.io/LWG/issue3790
The current proposed resolution is to just restore the C++20 functions
and not provide anything for the new types.

> If you want to have <cmath> done in a different way, e.g. the patch
> groups a lot of different function overloads by the floating point type,
> is that ok or do you want to have them one function at a time for all types,
> then next?

No, I think this way makes more sense. Otherwise the line count in the
file will baloon with all the repeated #if #endif directives.

The only comment I have about the <cmath> changes is that I think all
the new functions should be just 'constexpr' not 'inline
_GLIBCXX_CONSTEXPR'. The __STDCPP_FLOATN__ macros are only defined for
C++23, right? So _GLIBCXX_CONSTEXPR is always just 'constexpr' (it's
only something different for C++98), and that already implies 'inline'
too. So just:

constexpr _Float16
log10(_Float16 __x)
{ return _Float16(__builtin_log10f(__x)); }


> I could try to handle <complex> too, but am kind of lost there.
> The paper dropped the explicit std::complex specializations, can they stay
> around as is and should new overloads be added for the
> _Float*/__gnu_cxx::__bfloat16_t types?

The explicit specializations can stay, they do no harm.

I think to handle the new FP types we can modify the primary template
as shown in P1467. I don't think we'll need to add any new function
overloads for the new types.

I can take care of the <complex> changes.

> And I/O etc. support is missing, not sure I'm able to handle that and if it
> is e.g. possible to keep that support out of libstdc++.so.6, because what
> extended floating point types one has on a particular arch could change over
> time (I mean e.g. bfloat16_t support or float16_t support can be added
> etc.).

Yes, I think we can add the I/O functions as always_inline because all
they're going to do is convert the argument to float, double, or long
double and then call the existing overloads. There will be no new
virtual functions.

I can take care of that too.



> --- libstdc++-v3/include/bits/c++config.jj      2022-05-23 21:44:49.082847038 +0200
> +++ libstdc++-v3/include/bits/c++config 2022-10-14 22:32:55.411346463 +0200
> @@ -1,4 +1,4 @@
> -// Predefined symbols and macros -*- C++ -*-
> +       // Predefined symbols and macros -*- C++ -*-

This whitespace change looks accidental.

Apart from that and simplifying 'inline _GLIBCXX_CONSTEXPR' to just
'constexpr' this looks good for trunk.
  
Joseph Myers Oct. 17, 2022, 9:33 p.m. UTC | #2
On Mon, 17 Oct 2022, Jonathan Wakely via Gcc-patches wrote:

> > And I/O etc. support is missing, not sure I'm able to handle that and if it
> > is e.g. possible to keep that support out of libstdc++.so.6, because what
> > extended floating point types one has on a particular arch could change over
> > time (I mean e.g. bfloat16_t support or float16_t support can be added
> > etc.).
> 
> Yes, I think we can add the I/O functions as always_inline because all
> they're going to do is convert the argument to float, double, or long
> double and then call the existing overloads. There will be no new
> virtual functions.

As with fma, note that doing conversions from strings to floating-point is 
a case where doing the operation on float and then narrowing is 
technically incorrect because double rounding can occur (the rounded float 
result can be half way between two values of the narrower type, without 
that being the exact mathematical result) but the operation should be 
correctly rounding.  It's fine to use float or double operations in the 
other direction (floating-point to strings), of course.
  
Jonathan Wakely Oct. 17, 2022, 9:45 p.m. UTC | #3
On Mon, 17 Oct 2022 at 22:33, Joseph Myers <joseph@codesourcery.com> wrote:
>
> On Mon, 17 Oct 2022, Jonathan Wakely via Gcc-patches wrote:
>
> > > And I/O etc. support is missing, not sure I'm able to handle that and if it
> > > is e.g. possible to keep that support out of libstdc++.so.6, because what
> > > extended floating point types one has on a particular arch could change over
> > > time (I mean e.g. bfloat16_t support or float16_t support can be added
> > > etc.).
> >
> > Yes, I think we can add the I/O functions as always_inline because all
> > they're going to do is convert the argument to float, double, or long
> > double and then call the existing overloads. There will be no new
> > virtual functions.
>
> As with fma, note that doing conversions from strings to floating-point is
> a case where doing the operation on float and then narrowing is
> technically incorrect because double rounding can occur (the rounded float
> result can be half way between two values of the narrower type, without
> that being the exact mathematical result) but the operation should be
> correctly rounding.  It's fine to use float or double operations in the
> other direction (floating-point to strings), of course.

Yes, this is called out in the C++23 draft:

[ Note: When the extended floating-point type has a floating-point
conversion rank that is not equal to the rank of any standard
floating-point type, then double rounding during the conversion can
result in inaccurate results. from_chars can be used in situations
where maximum accuracy is important. - end note ]

The alternative is an ABI break, which we didn't want to force on
implementors. For libstdc++ we're not going to break the ABI, so we're
going to live with the double rounding.
  
Jakub Jelinek Oct. 17, 2022, 9:50 p.m. UTC | #4
On Mon, Oct 17, 2022 at 09:33:02PM +0000, Joseph Myers wrote:
> > > And I/O etc. support is missing, not sure I'm able to handle that and if it
> > > is e.g. possible to keep that support out of libstdc++.so.6, because what
> > > extended floating point types one has on a particular arch could change over
> > > time (I mean e.g. bfloat16_t support or float16_t support can be added
> > > etc.).
> > 
> > Yes, I think we can add the I/O functions as always_inline because all
> > they're going to do is convert the argument to float, double, or long
> > double and then call the existing overloads. There will be no new
> > virtual functions.
> 
> As with fma, note that doing conversions from strings to floating-point is 
> a case where doing the operation on float and then narrowing is 
> technically incorrect because double rounding can occur (the rounded float 
> result can be half way between two values of the narrower type, without 
> that being the exact mathematical result) but the operation should be 
> correctly rounding.  It's fine to use float or double operations in the 
> other direction (floating-point to strings), of course.

That is true, but for istream and ostream that is what the standard
requires.  This is because there are required facets to be called and
they are available just for float/double/long double and it would be
an ABI change to allow more.
For extended floating point wider than long double it is implementation
defined what happens.
And otherwise, there is
[ Note: When the extended floating-point type has a floating-point
conversion rank that is not equal to the rank of any standard floating-point
type, then double rounding during the conversion can result in inaccurate
results.  from_chars can be used in situations where maximum accuracy is
important.  - end note ]
As for <charconv>, I think we'll need to implement both directions,
though perhaps the float16_t or bfloat16_t to_chars can be partly or fully
implemented using the float to_chars.

	Jakub
  

Patch

--- libstdc++-v3/include/std/stdfloat.jj	2022-10-14 22:32:55.409346491 +0200
+++ libstdc++-v3/include/std/stdfloat	2022-10-14 22:32:55.408346505 +0200
@@ -0,0 +1,62 @@ 
+// <stdfloat> -*- C++ -*-
+
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This 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 General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/stdfloat
+ *  This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_STDFLOAT
+#define _GLIBCXX_STDFLOAT 1
+
+#if __cplusplus > 202002L
+#include <bits/c++config.h>
+
+namespace std
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  #ifdef __STDCPP_FLOAT16_T__
+  using float16_t = _Float16;
+  #endif
+
+  #ifdef __STDCPP_FLOAT32_T__
+  using float32_t = _Float32;
+  #endif
+
+  #ifdef __STDCPP_FLOAT64_T__
+  using float64_t = _Float64;
+  #endif
+
+  #ifdef __STDCPP_FLOAT128_T__
+  using float128_t = _Float128;
+  #endif
+
+  #ifdef __STDCPP_BFLOAT16_T__
+  using bfloat16_t = __gnu_cxx::__bfloat16_t;
+  #endif
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+#endif // C++23
+#endif // _GLIBCXX_STDFLOAT
--- libstdc++-v3/include/std/numbers.jj	2022-09-29 22:16:25.227338468 +0200
+++ libstdc++-v3/include/std/numbers	2022-10-14 22:32:55.409346491 +0200
@@ -133,72 +133,98 @@  namespace numbers
   inline constexpr double egamma = egamma_v<double>;
   inline constexpr double phi = phi_v<double>;
 
+#define __glibcxx_numbers(TYPE, SUFFIX) \
+  /* e */						\
+  template<>						\
+    inline constexpr TYPE e_v<TYPE>			\
+      = 2.718281828459045235360287471352662498##SUFFIX;	\
+							\
+  /* log_2 e */						\
+  template<>						\
+    inline constexpr TYPE log2e_v<TYPE>			\
+      = 1.442695040888963407359924681001892137##SUFFIX;	\
+							\
+  /* log_10 e */					\
+  template<>						\
+    inline constexpr TYPE log10e_v<TYPE>		\
+      = 0.434294481903251827651128918916605082##SUFFIX;	\
+							\
+  /* pi */						\
+  template<>						\
+    inline constexpr TYPE pi_v<TYPE>			\
+      = 3.141592653589793238462643383279502884##SUFFIX;	\
+							\
+  /* 1/pi */						\
+  template<>						\
+    inline constexpr TYPE inv_pi_v<TYPE>		\
+      = 0.318309886183790671537767526745028724##SUFFIX;	\
+							\
+  /* 1/sqrt(pi) */					\
+  template<>						\
+    inline constexpr TYPE inv_sqrtpi_v<TYPE>		\
+      = 0.564189583547756286948079451560772586##SUFFIX;	\
+							\
+  /* log_e 2 */						\
+  template<>						\
+    inline constexpr TYPE ln2_v<TYPE>			\
+      = 0.693147180559945309417232121458176568##SUFFIX;	\
+							\
+  /* log_e 10 */					\
+  template<>						\
+    inline constexpr TYPE ln10_v<TYPE>			\
+      = 2.302585092994045684017991454684364208##SUFFIX;	\
+							\
+  /* sqrt(2) */						\
+  template<>						\
+    inline constexpr TYPE sqrt2_v<TYPE>			\
+      = 1.414213562373095048801688724209698079##SUFFIX;	\
+							\
+  /* sqrt(3) */						\
+  template<>						\
+    inline constexpr TYPE sqrt3_v<TYPE>			\
+      = 1.732050807568877293527446341505872367##SUFFIX;	\
+							\
+  /* 1/sqrt(3) */					\
+  template<>						\
+    inline constexpr TYPE inv_sqrt3_v<TYPE>		\
+      = 0.577350269189625764509148780501957456##SUFFIX;	\
+							\
+  /* The Euler-Mascheroni constant */			\
+  template<>						\
+    inline constexpr TYPE egamma_v<TYPE>		\
+      = 0.577215664901532860606512090082402431##SUFFIX;	\
+							\
+  /* The golden ratio, (1+sqrt(5))/2 */			\
+  template<>						\
+    inline constexpr TYPE phi_v<TYPE>			\
+      = 1.618033988749894848204586834365638118##SUFFIX
+
+#ifdef __STDCPP_FLOAT16_T__
+__glibcxx_numbers (_Float16, F16);
+#endif
+
+#ifdef __STDCPP_FLOAT32_T__
+__glibcxx_numbers (_Float32, F32);
+#endif
+
+#ifdef __STDCPP_FLOAT64_T__
+__glibcxx_numbers (_Float64, F64);
+#endif
+
+#ifdef __STDCPP_FLOAT128_T__
+__glibcxx_numbers (_Float128, F128);
+#endif
+
+#ifdef __STDCPP_BFLOAT128_T__
+__glibcxx_numbers (__gnu_cxx::__bfloat16_t, BF16);
+#endif
+
 #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
-  template<>
-    inline constexpr __float128 e_v<__float128>
-      = 2.718281828459045235360287471352662498Q;
-
-  /// log_2 e
-  template<>
-    inline constexpr __float128 log2e_v<__float128>
-      = 1.442695040888963407359924681001892137Q;
-
-  /// log_10 e
-  template<>
-    inline constexpr __float128 log10e_v<__float128>
-      = 0.434294481903251827651128918916605082Q;
-
-  /// pi
-  template<>
-    inline constexpr __float128 pi_v<__float128>
-      = 3.141592653589793238462643383279502884Q;
-
-  /// 1/pi
-  template<>
-    inline constexpr __float128 inv_pi_v<__float128>
-      = 0.318309886183790671537767526745028724Q;
-
-  /// 1/sqrt(pi)
-  template<>
-    inline constexpr __float128 inv_sqrtpi_v<__float128>
-      = 0.564189583547756286948079451560772586Q;
-
-  /// log_e 2
-  template<>
-    inline constexpr __float128 ln2_v<__float128>
-      = 0.693147180559945309417232121458176568Q;
-
-  /// log_e 10
-  template<>
-    inline constexpr __float128 ln10_v<__float128>
-      = 2.302585092994045684017991454684364208Q;
-
-  /// sqrt(2)
-  template<>
-    inline constexpr __float128 sqrt2_v<__float128>
-      = 1.414213562373095048801688724209698079Q;
-
-  /// sqrt(3)
-  template<>
-    inline constexpr __float128 sqrt3_v<__float128>
-      = 1.732050807568877293527446341505872367Q;
-
-  /// 1/sqrt(3)
-  template<>
-    inline constexpr __float128 inv_sqrt3_v<__float128>
-      = 0.577350269189625764509148780501957456Q;
-
-  /// The Euler-Mascheroni constant
-  template<>
-    inline constexpr __float128 egamma_v<__float128>
-      = 0.577215664901532860606512090082402431Q;
-
-  /// The golden ratio, (1+sqrt(5))/2
-  template<>
-    inline constexpr __float128 phi_v<__float128>
-      = 1.618033988749894848204586834365638118Q;
+__glibcxx_numbers (__float128, Q);
 #endif // USE_FLOAT128
 
+#undef __glibcxx_numbers
+
 } // namespace numbers
 /// @}
 _GLIBCXX_END_NAMESPACE_VERSION
--- libstdc++-v3/include/std/atomic.jj	2022-09-29 22:16:25.227338468 +0200
+++ libstdc++-v3/include/std/atomic	2022-10-14 22:32:55.410346477 +0200
@@ -1625,6 +1625,91 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using __atomic_float<long double>::operator=;
     };
 
+#ifdef __STDCPP_FLOAT16_T__
+  template<>
+    struct atomic<_Float16> : __atomic_float<_Float16>
+    {
+      atomic() noexcept = default;
+
+      constexpr
+      atomic(_Float16 __fp) noexcept : __atomic_float<_Float16>(__fp)
+      { }
+
+      atomic& operator=(const atomic&) volatile = delete;
+      atomic& operator=(const atomic&) = delete;
+
+      using __atomic_float<_Float16>::operator=;
+    };
+#endif
+
+#ifdef __STDCPP_FLOAT32_T__
+  template<>
+    struct atomic<_Float32> : __atomic_float<_Float32>
+    {
+      atomic() noexcept = default;
+
+      constexpr
+      atomic(_Float32 __fp) noexcept : __atomic_float<_Float32>(__fp)
+      { }
+
+      atomic& operator=(const atomic&) volatile = delete;
+      atomic& operator=(const atomic&) = delete;
+
+      using __atomic_float<_Float32>::operator=;
+    };
+#endif
+
+#ifdef __STDCPP_FLOAT64_T__
+  template<>
+    struct atomic<_Float64> : __atomic_float<_Float64>
+    {
+      atomic() noexcept = default;
+
+      constexpr
+      atomic(_Float64 __fp) noexcept : __atomic_float<_Float64>(__fp)
+      { }
+
+      atomic& operator=(const atomic&) volatile = delete;
+      atomic& operator=(const atomic&) = delete;
+
+      using __atomic_float<_Float64>::operator=;
+    };
+#endif
+
+#ifdef __STDCPP_FLOAT128_T__
+  template<>
+    struct atomic<_Float128> : __atomic_float<_Float128>
+    {
+      atomic() noexcept = default;
+
+      constexpr
+      atomic(_Float128 __fp) noexcept : __atomic_float<_Float128>(__fp)
+      { }
+
+      atomic& operator=(const atomic&) volatile = delete;
+      atomic& operator=(const atomic&) = delete;
+
+      using __atomic_float<_Float128>::operator=;
+    };
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+  template<>
+    struct atomic<__gnu_cxx::__bfloat16_t> : __atomic_float<__gnu_cxx::__bfloat16_t>
+    {
+      atomic() noexcept = default;
+
+      constexpr
+      atomic(__gnu_cxx::__bfloat16_t __fp) noexcept : __atomic_float<__gnu_cxx::__bfloat16_t>(__fp)
+      { }
+
+      atomic& operator=(const atomic&) volatile = delete;
+      atomic& operator=(const atomic&) = delete;
+
+      using __atomic_float<__gnu_cxx::__bfloat16_t>::operator=;
+    };
+#endif
+
 #define __cpp_lib_atomic_ref 201806L
 
   /// Class template to provide atomic operations on a non-atomic variable.
--- libstdc++-v3/include/std/type_traits.jj	2022-10-11 12:10:42.236890466 +0200
+++ libstdc++-v3/include/std/type_traits	2022-10-14 22:32:55.410346477 +0200
@@ -459,6 +459,36 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __is_floating_point_helper<long double>
     : public true_type { };
 
+#ifdef __STDCPP_FLOAT16_T__
+  template<>
+    struct __is_floating_point_helper<_Float16>
+    : public true_type { };
+#endif
+
+#ifdef __STDCPP_FLOAT32_T__
+  template<>
+    struct __is_floating_point_helper<_Float32>
+    : public true_type { };
+#endif
+
+#ifdef __STDCPP_FLOAT64_T__
+  template<>
+    struct __is_floating_point_helper<_Float64>
+    : public true_type { };
+#endif
+
+#ifdef __STDCPP_FLOAT128_T__
+  template<>
+    struct __is_floating_point_helper<_Float128>
+    : public true_type { };
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+  template<>
+    struct __is_floating_point_helper<__gnu_cxx::__bfloat16_t>
+    : public true_type { };
+#endif
+
 #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
   template<>
     struct __is_floating_point_helper<__float128>
--- libstdc++-v3/include/std/limits.jj	2022-10-05 21:23:02.984826675 +0200
+++ libstdc++-v3/include/std/limits	2022-10-14 22:32:55.000000000 +0200
@@ -1890,6 +1890,201 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #undef __glibcxx_long_double_traps
 #undef __glibcxx_long_double_tinyness_before
 
+#if __cplusplus > 202202L
+
+#define __glibcxx_concat3_(P,M,S) P ## M ## S
+#define __glibcxx_concat3(P,M,S) __glibcxx_concat3_ (P,M,S)
+
+#define __glibcxx_float_n(BITSIZE)					\
+  __extension__								\
+  template<>								\
+    struct numeric_limits<_Float##BITSIZE>				\
+    {									\
+      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;		\
+									\
+      static _GLIBCXX_CONSTEXPR _Float##BITSIZE				\
+      min() _GLIBCXX_USE_NOEXCEPT					\
+      { return __glibcxx_concat3 (__FLT, BITSIZE, _MIN__); }		\
+									\
+      static _GLIBCXX_CONSTEXPR _Float##BITSIZE				\
+      max() _GLIBCXX_USE_NOEXCEPT					\
+      { return __glibcxx_concat3 (__FLT, BITSIZE, _MAX__); }		\
+									\
+      static _GLIBCXX_CONSTEXPR _Float##BITSIZE				\
+      lowest() noexcept							\
+      { return -__glibcxx_concat3 (__FLT, BITSIZE, _MAX__); }		\
+									\
+      static _GLIBCXX_USE_CONSTEXPR int digits				\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _MANT_DIG__);		\
+      static _GLIBCXX_USE_CONSTEXPR int digits10			\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _DIG__);			\
+      static _GLIBCXX_USE_CONSTEXPR int max_digits10			\
+	= __glibcxx_max_digits10 (__glibcxx_concat3 (__FLT, BITSIZE,	\
+						     _MANT_DIG__));	\
+      static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;		\
+      static _GLIBCXX_USE_CONSTEXPR bool is_integer = false;		\
+      static _GLIBCXX_USE_CONSTEXPR bool is_exact = false;		\
+      static _GLIBCXX_USE_CONSTEXPR int radix				\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _RADIX__);			\
+									\
+      static _GLIBCXX_CONSTEXPR _Float##BITSIZE				\
+      epsilon() _GLIBCXX_USE_NOEXCEPT					\
+      { return __glibcxx_concat3 (__FLT, BITSIZE, _EPSILON__); }	\
+									\
+      static _GLIBCXX_CONSTEXPR _Float##BITSIZE 			\
+      round_error() _GLIBCXX_USE_NOEXCEPT { return 0.5F##BITSIZE; }	\
+									\
+      static _GLIBCXX_USE_CONSTEXPR int min_exponent			\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _MIN_EXP__);		\
+      static _GLIBCXX_USE_CONSTEXPR int min_exponent10			\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _MIN_10_EXP__);		\
+      static _GLIBCXX_USE_CONSTEXPR int max_exponent			\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _MAX_EXP__);		\
+      static _GLIBCXX_USE_CONSTEXPR int max_exponent10			\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _MAX_10_EXP__);		\
+									\
+      static _GLIBCXX_USE_CONSTEXPR bool has_infinity			\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _HAS_INFINITY__);		\
+      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN			\
+	= __glibcxx_concat3 (__FLT, BITSIZE, _HAS_QUIET_NAN__);		\
+      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN		\
+	= has_quiet_NaN;						\
+      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm	\
+	= bool(__glibcxx_concat3 (__FLT, BITSIZE, _HAS_DENORM__))	\
+	  ? denorm_present : denorm_absent;				\
+      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;	\
+									\
+      static _GLIBCXX_CONSTEXPR _Float##BITSIZE				\
+      infinity() _GLIBCXX_USE_NOEXCEPT					\
+      { return __builtin_huge_valf##BITSIZE(); }			\
+									\
+      static _GLIBCXX_CONSTEXPR _Float##BITSIZE				\
+      quiet_NaN() _GLIBCXX_USE_NOEXCEPT					\
+      { return __builtin_nanf##BITSIZE(""); }				\
+									\
+      static _GLIBCXX_CONSTEXPR _Float##BITSIZE				\
+      signaling_NaN() _GLIBCXX_USE_NOEXCEPT				\
+      { return __builtin_nansf##BITSIZE(""); }				\
+									\
+      static _GLIBCXX_CONSTEXPR _Float##BITSIZE				\
+      denorm_min() _GLIBCXX_USE_NOEXCEPT				\
+      { return __glibcxx_concat3 (__FLT, BITSIZE, _DENORM_MIN__); }	\
+									\
+      static _GLIBCXX_USE_CONSTEXPR bool is_iec559			\
+	= as_infinity && has_quiet_NaN && has_denorm == denorm_present;	\
+      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; 		\
+      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false; 		\
+									\
+      static _GLIBCXX_USE_CONSTEXPR bool traps = false; 		\
+      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; 	\
+      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style 	\
+	= round_to_nearest; 						\
+    }; 									\
+
+#ifdef __STDCPP_FLOAT16_T__
+__glibcxx_float_n(16)
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+__glibcxx_float_n(32)
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+__glibcxx_float_n(64)
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+__glibcxx_float_n(128)
+#endif
+#undef __glibcxx_float_n
+#undef __glibcxx_concat3
+#undef __glibcxx_concat3_
+
+#ifdef __STDCPP_BFLOAT16_T__
+  __extension__
+  template<>
+    struct numeric_limits<__gnu_cxx::__bfloat16_t>
+    {
+      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;
+
+      static _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+      min() _GLIBCXX_USE_NOEXCEPT
+      { return __BFLT16_MIN__; }
+
+      static _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+      max() _GLIBCXX_USE_NOEXCEPT
+      { return __BFLT16_MAX__; }
+
+      static _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+      lowest() noexcept
+      { return -__BFLT16_MAX__; }
+
+      static _GLIBCXX_USE_CONSTEXPR int digits
+	= __BFLT16_MANT_DIG__;
+      static _GLIBCXX_USE_CONSTEXPR int digits10
+	= __BFLT16_DIG__;
+      static _GLIBCXX_USE_CONSTEXPR int max_digits10
+	= __glibcxx_max_digits10 (__BFLT16_MANT_DIG__);
+      static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
+      static _GLIBCXX_USE_CONSTEXPR bool is_integer = false;
+      static _GLIBCXX_USE_CONSTEXPR bool is_exact = false;
+      static _GLIBCXX_USE_CONSTEXPR int radix
+	= __BFLT16_RADIX__;
+
+      static _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+      epsilon() _GLIBCXX_USE_NOEXCEPT
+      { return __BFLT16_EPSILON__; }
+
+      static _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+      round_error() _GLIBCXX_USE_NOEXCEPT { return 0.5BF16; }
+
+      static _GLIBCXX_USE_CONSTEXPR int min_exponent
+	= __BFLT16_MIN_EXP__;
+      static _GLIBCXX_USE_CONSTEXPR int min_exponent10
+	= __BFLT16_MIN_10_EXP__;
+      static _GLIBCXX_USE_CONSTEXPR int max_exponent
+	= __BFLT16_MAX_EXP__;
+      static _GLIBCXX_USE_CONSTEXPR int max_exponent10
+	= __BFLT16_MAX_10_EXP__;
+
+      static _GLIBCXX_USE_CONSTEXPR bool has_infinity
+	= __BFLT16_HAS_INFINITY__;
+      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN
+	= __BFLT16_HAS_QUIET_NAN__;
+      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN
+	= has_quiet_NaN;
+      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
+	= bool(__BFLT16_HAS_DENORM__)
+	  ? denorm_present : denorm_absent;
+      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;
+
+      static _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+      infinity() _GLIBCXX_USE_NOEXCEPT
+      { return __gnu_cxx::__bfloat16_t(__builtin_huge_valf()); }
+
+      static _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+      quiet_NaN() _GLIBCXX_USE_NOEXCEPT
+      { return __gnu_cxx::__bfloat16_t(__builtin_nanf("")); }
+
+      static _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+      signaling_NaN() _GLIBCXX_USE_NOEXCEPT
+      { return __builtin_nansf16b(""); }
+
+      static _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+      denorm_min() _GLIBCXX_USE_NOEXCEPT
+      { return __BFLT16_DENORM_MIN__; }
+
+      static _GLIBCXX_USE_CONSTEXPR bool is_iec559
+	= as_infinity && has_quiet_NaN && has_denorm == denorm_present;
+      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
+      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;
+
+      static _GLIBCXX_USE_CONSTEXPR bool traps = false;
+      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
+      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
+	= round_to_nearest;
+    };
+#endif
+
+#endif
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
--- libstdc++-v3/include/bits/std_abs.h.jj	2022-01-11 22:31:41.490757144 +0100
+++ libstdc++-v3/include/bits/std_abs.h	2022-10-14 22:32:55.411346463 +0200
@@ -97,6 +97,40 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; }
 #endif
 
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _GLIBCXX_CONSTEXPR _Float16
+  abs(_Float16 __x)
+  { return _Float16(__builtin_fabsf(__x)); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _GLIBCXX_CONSTEXPR _Float32
+  abs(_Float32 __x)
+  { return __builtin_fabsf(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  inline _GLIBCXX_CONSTEXPR _Float64
+  abs(_Float64 __x)
+  { return __builtin_fabs(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+  inline _GLIBCXX_CONSTEXPR _Float128
+  abs(_Float128 __x)
+  { return __builtin_fabsl(__x); }
+#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
+  inline _GLIBCXX_CONSTEXPR _Float128
+  abs(_Float128 __x)
+  { return __builtin_fabsf128(__x); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  abs(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_fabsf(__x)); }
+#endif
+
 #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
   __extension__ inline _GLIBCXX_CONSTEXPR
   __float128
--- libstdc++-v3/include/bits/c++config.jj	2022-05-23 21:44:49.082847038 +0200
+++ libstdc++-v3/include/bits/c++config	2022-10-14 22:32:55.411346463 +0200
@@ -1,4 +1,4 @@ 
-// Predefined symbols and macros -*- C++ -*-
+	// Predefined symbols and macros -*- C++ -*-
 
 // Copyright (C) 1997-2022 Free Software Foundation, Inc.
 //
@@ -796,6 +796,20 @@  namespace std
 # define _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 1
 #endif
 
+// Define if long double has the IEEE binary128 format.
+#if __LDBL_MANT_DIG__ == 113 \
+  && __LDBL_MIN_EXP__ == -16381 \
+  && __LDBL_MAX_EXP__ == 16384
+# define _GLIBCXX_LDOUBLE_IS_IEEE_BINARY128 1
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+namespace __gnu_cxx
+{
+  using __bfloat16_t = decltype(0.0bf16);
+}
+#endif
+
 #ifdef __has_builtin
 # ifdef __is_identifier
 // Intel and older Clang require !__is_identifier for some built-ins:
--- libstdc++-v3/include/c_global/cmath.jj	2022-10-03 22:45:46.093435123 +0200
+++ libstdc++-v3/include/c_global/cmath	2022-10-14 22:32:55.412346449 +0200
@@ -515,6 +515,564 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     tanh(_Tp __x)
     { return __builtin_tanh(__x); }
 
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _GLIBCXX_CONSTEXPR _Float16
+  acos(_Float16 __x)
+  { return _Float16(__builtin_acosf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  asin(_Float16 __x)
+  { return _Float16(__builtin_asinf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  atan(_Float16 __x)
+  { return _Float16(__builtin_atanf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  atan2(_Float16 __y, _Float16 __x)
+  { return _Float16(__builtin_atan2f(__y, __x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  ceil(_Float16 __x)
+  { return _Float16(__builtin_ceilf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  cos(_Float16 __x)
+  { return _Float16(__builtin_cosf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  cosh(_Float16 __x)
+  { return _Float16(__builtin_coshf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  exp(_Float16 __x)
+  { return _Float16(__builtin_expf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  fabs(_Float16 __x)
+  { return _Float16(__builtin_fabsf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  floor(_Float16 __x)
+  { return _Float16(__builtin_floorf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  fmod(_Float16 __x, _Float16 __y)
+  { return _Float16(__builtin_fmodf(__x, __y)); }
+
+  inline _Float16
+  frexp(_Float16 __x, int* __exp)
+  { return _Float16(__builtin_frexpf(__x, __exp)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  ldexp(_Float16 __x, int __exp)
+  { return _Float16(__builtin_ldexpf(__x, __exp)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  log(_Float16 __x)
+  { return _Float16(__builtin_logf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  log10(_Float16 __x)
+  { return _Float16(__builtin_log10f(__x)); }
+
+  inline _Float16
+  modf(_Float16 __x, _Float16* __iptr)
+  {
+    float __i, __ret = __builtin_modff(__x, &__i);
+    *__iptr = _Float16(__i);
+    return _Float16(__ret);
+  }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  pow(_Float16 __x, _Float16 __y)
+  { return _Float16(__builtin_powf(__x, __y)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  sin(_Float16 __x)
+  { return _Float16(__builtin_sinf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  sinh(_Float16 __x)
+  { return _Float16(__builtin_sinhf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  sqrt(_Float16 __x)
+  { return _Float16(__builtin_sqrtf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  tan(_Float16 __x)
+  { return _Float16(__builtin_tanf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR _Float16
+  tanh(_Float16 __x)
+  { return _Float16(__builtin_tanhf(__x)); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _GLIBCXX_CONSTEXPR _Float32
+  acos(_Float32 __x)
+  { return __builtin_acosf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  asin(_Float32 __x)
+  { return __builtin_asinf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  atan(_Float32 __x)
+  { return __builtin_atanf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  atan2(_Float32 __y, _Float32 __x)
+  { return __builtin_atan2f(__y, __x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  ceil(_Float32 __x)
+  { return __builtin_ceilf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  cos(_Float32 __x)
+  { return __builtin_cosf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  cosh(_Float32 __x)
+  { return __builtin_coshf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  exp(_Float32 __x)
+  { return __builtin_expf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  fabs(_Float32 __x)
+  { return __builtin_fabsf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  floor(_Float32 __x)
+  { return __builtin_floorf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  fmod(_Float32 __x, _Float32 __y)
+  { return __builtin_fmodf(__x, __y); }
+
+  inline _Float32
+  frexp(_Float32 __x, int* __exp)
+  { return __builtin_frexpf(__x, __exp); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  ldexp(_Float32 __x, int __exp)
+  { return __builtin_ldexpf(__x, __exp); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  log(_Float32 __x)
+  { return __builtin_logf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  log10(_Float32 __x)
+  { return __builtin_log10f(__x); }
+
+  inline _Float32
+  modf(_Float32 __x, _Float32* __iptr)
+  {
+    float __i, __ret = __builtin_modff(__x, &__i);
+    *__iptr = __i;
+    return __ret;
+  }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  pow(_Float32 __x, _Float32 __y)
+  { return __builtin_powf(__x, __y); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  sin(_Float32 __x)
+  { return __builtin_sinf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  sinh(_Float32 __x)
+  { return __builtin_sinhf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  sqrt(_Float32 __x)
+  { return __builtin_sqrtf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  tan(_Float32 __x)
+  { return __builtin_tanf(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float32
+  tanh(_Float32 __x)
+  { return __builtin_tanhf(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  inline _GLIBCXX_CONSTEXPR _Float64
+  acos(_Float64 __x)
+  { return __builtin_acos(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  asin(_Float64 __x)
+  { return __builtin_asin(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  atan(_Float64 __x)
+  { return __builtin_atan(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  atan2(_Float64 __y, _Float64 __x)
+  { return __builtin_atan2(__y, __x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  ceil(_Float64 __x)
+  { return __builtin_ceil(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  cos(_Float64 __x)
+  { return __builtin_cos(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  cosh(_Float64 __x)
+  { return __builtin_cosh(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  exp(_Float64 __x)
+  { return __builtin_exp(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  fabs(_Float64 __x)
+  { return __builtin_fabs(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  floor(_Float64 __x)
+  { return __builtin_floor(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  fmod(_Float64 __x, _Float64 __y)
+  { return __builtin_fmod(__x, __y); }
+
+  inline _Float64
+  frexp(_Float64 __x, int* __exp)
+  { return __builtin_frexp(__x, __exp); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  ldexp(_Float64 __x, int __exp)
+  { return __builtin_ldexp(__x, __exp); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  log(_Float64 __x)
+  { return __builtin_log(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  log10(_Float64 __x)
+  { return __builtin_log10(__x); }
+
+  inline _Float64
+  modf(_Float64 __x, _Float64* __iptr)
+  {
+    double __i, __ret = __builtin_modf(__x, &__i);
+    *__iptr = __i;
+    return __ret;
+  }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  pow(_Float64 __x, _Float64 __y)
+  { return __builtin_pow(__x, __y); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  sin(_Float64 __x)
+  { return __builtin_sin(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  sinh(_Float64 __x)
+  { return __builtin_sinh(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  sqrt(_Float64 __x)
+  { return __builtin_sqrt(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  tan(_Float64 __x)
+  { return __builtin_tan(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float64
+  tanh(_Float64 __x)
+  { return __builtin_tanh(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+  inline _GLIBCXX_CONSTEXPR _Float128
+  acos(_Float128 __x)
+  { return __builtin_acosl(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  asin(_Float128 __x)
+  { return __builtin_asinl(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  atan(_Float128 __x)
+  { return __builtin_atanl(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  atan2(_Float128 __y, _Float128 __x)
+  { return __builtin_atan2l(__y, __x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  ceil(_Float128 __x)
+  { return __builtin_ceill(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  cos(_Float128 __x)
+  { return __builtin_cosl(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  cosh(_Float128 __x)
+  { return __builtin_coshl(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  exp(_Float128 __x)
+  { return __builtin_expl(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  fabs(_Float128 __x)
+  { return __builtin_fabsl(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  floor(_Float128 __x)
+  { return __builtin_floorl(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  fmod(_Float128 __x, _Float128 __y)
+  { return __builtin_fmodl(__x, __y); }
+
+  inline _Float128
+  frexp(_Float128 __x, int* __exp)
+  { return __builtin_frexpl(__x, __exp); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  ldexp(_Float128 __x, int __exp)
+  { return __builtin_ldexpl(__x, __exp); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  log(_Float128 __x)
+  { return __builtin_logl(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  log10(_Float128 __x)
+  { return __builtin_log10l(__x); }
+
+  inline _Float128
+  modf(_Float128 __x, _Float128* __iptr)
+  {
+    long double __i, __ret = __builtin_modfl(__x, &__i);
+    *__iptr = __i;
+    return __ret;
+  }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  pow(_Float128 __x, _Float128 __y)
+  { return __builtin_powl(__x, __y); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  sin(_Float128 __x)
+  { return __builtin_sinl(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  sinh(_Float128 __x)
+  { return __builtin_sinhl(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  sqrt(_Float128 __x)
+  { return __builtin_sqrtl(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  tan(_Float128 __x)
+  { return __builtin_tanl(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  tanh(_Float128 __x)
+  { return __builtin_tanhl(__x); }
+#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
+  inline _GLIBCXX_CONSTEXPR _Float128
+  acos(_Float128 __x)
+  { return __builtin_acosf128(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  asin(_Float128 __x)
+  { return __builtin_asinf128(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  atan(_Float128 __x)
+  { return __builtin_atanf128(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  atan2(_Float128 __y, _Float128 __x)
+  { return __builtin_atan2f128(__y, __x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  ceil(_Float128 __x)
+  { return __builtin_ceilf128(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  cos(_Float128 __x)
+  { return __builtin_cosf128(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  cosh(_Float128 __x)
+  { return __builtin_coshf128(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  exp(_Float128 __x)
+  { return __builtin_expf128(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  fabs(_Float128 __x)
+  { return __builtin_fabsf128(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  floor(_Float128 __x)
+  { return __builtin_floorf128(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  fmod(_Float128 __x, _Float128 __y)
+  { return __builtin_fmodf128(__x, __y); }
+
+  inline _Float128
+  frexp(_Float128 __x, int* __exp)
+  { return __builtin_frexpf128(__x, __exp); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  ldexp(_Float128 __x, int __exp)
+  { return __builtin_ldexpf128(__x, __exp); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  log(_Float128 __x)
+  { return __builtin_logf128(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  log10(_Float128 __x)
+  { return __builtin_log10f128(__x); }
+
+  inline _Float128
+  modf(_Float128 __x, _Float128* __iptr)
+  { return __builtin_modff128(__x, __iptr); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  pow(_Float128 __x, _Float128 __y)
+  { return __builtin_powf128(__x, __y); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  sin(_Float128 __x)
+  { return __builtin_sinf128(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  sinh(_Float128 __x)
+  { return __builtin_sinhf128(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  sqrt(_Float128 __x)
+  { return __builtin_sqrtf128(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  tan(_Float128 __x)
+  { return __builtin_tanf128(__x); }
+
+  inline _GLIBCXX_CONSTEXPR _Float128
+  tanh(_Float128 __x)
+  { return __builtin_tanhf128(__x); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  acos(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_acosf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  asin(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_asinf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  atan(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_atanf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  atan2(__gnu_cxx::__bfloat16_t __y, __gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_atan2f(__y, __x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  ceil(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_ceilf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  cos(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_cosf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  cosh(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_coshf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  exp(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_expf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  fabs(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_fabsf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  floor(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_floorf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  fmod(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_fmodf(__x, __y)); }
+
+  inline __gnu_cxx::__bfloat16_t
+  frexp(__gnu_cxx::__bfloat16_t __x, int* __exp)
+  { return __gnu_cxx::__bfloat16_t(__builtin_frexpf(__x, __exp)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  ldexp(__gnu_cxx::__bfloat16_t __x, int __exp)
+  { return __gnu_cxx::__bfloat16_t(__builtin_ldexpf(__x, __exp)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  log(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_logf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  log10(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_log10f(__x)); }
+
+  inline __gnu_cxx::__bfloat16_t
+  modf(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t* __iptr)
+  {
+    float __i, __ret = __builtin_modff(__x, &__i);
+    *__iptr = __gnu_cxx::__bfloat16_t(__i);
+    return __gnu_cxx::__bfloat16_t(__ret);
+  }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  pow(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_powf(__x, __y)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  sin(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_sinf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  sinh(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_sinhf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  sqrt(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_sqrtf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  tan(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_tanf(__x)); }
+
+  inline _GLIBCXX_CONSTEXPR __gnu_cxx::__bfloat16_t
+  tanh(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_tanhf(__x)); }
+#endif
+
 #if _GLIBCXX_USE_C99_MATH
 #if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC
 
@@ -948,6 +1506,262 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
 #endif // C++11
+
+#ifdef __STDCPP_FLOAT16_T__
+  constexpr int
+  fpclassify(_Float16 __x)
+  { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+				FP_SUBNORMAL, FP_ZERO, __x); }
+
+  constexpr bool
+  isfinite(_Float16 __x)
+  { return __builtin_isfinite(__x); }
+
+  constexpr bool
+  isinf(_Float16 __x)
+  { return __builtin_isinf(__x); }
+
+  constexpr bool
+  isnan(_Float16 __x)
+  { return __builtin_isnan(__x); }
+
+  constexpr bool
+  isnormal(_Float16 __x)
+  { return __builtin_isnormal(__x); }
+
+  constexpr bool
+  signbit(_Float16 __x)
+  { return __builtin_signbit(__x); }
+
+  constexpr bool
+  isgreater(_Float16 __x, _Float16 __y)
+  { return __builtin_isgreater(__x, __y); }
+
+  constexpr bool
+  isgreaterequal(_Float16 __x, _Float16 __y)
+  { return __builtin_isgreaterequal(__x, __y); }
+
+  constexpr bool
+  isless(_Float16 __x, _Float16 __y)
+  { return __builtin_isless(__x, __y); }
+
+  constexpr bool
+  islessequal(_Float16 __x, _Float16 __y)
+  { return __builtin_islessequal(__x, __y); }
+
+  constexpr bool
+  islessgreater(_Float16 __x, _Float16 __y)
+  { return __builtin_islessgreater(__x, __y); }
+
+  constexpr bool
+  isunordered(_Float16 __x, _Float16 __y)
+  { return __builtin_isunordered(__x, __y); }
+#endif
+
+#ifdef __STDCPP_FLOAT32_T__
+  constexpr int
+  fpclassify(_Float32 __x)
+  { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+				FP_SUBNORMAL, FP_ZERO, __x); }
+
+  constexpr bool
+  isfinite(_Float32 __x)
+  { return __builtin_isfinite(__x); }
+
+  constexpr bool
+  isinf(_Float32 __x)
+  { return __builtin_isinf(__x); }
+
+  constexpr bool
+  isnan(_Float32 __x)
+  { return __builtin_isnan(__x); }
+
+  constexpr bool
+  isnormal(_Float32 __x)
+  { return __builtin_isnormal(__x); }
+
+  constexpr bool
+  signbit(_Float32 __x)
+  { return __builtin_signbit(__x); }
+
+  constexpr bool
+  isgreater(_Float32 __x, _Float32 __y)
+  { return __builtin_isgreater(__x, __y); }
+
+  constexpr bool
+  isgreaterequal(_Float32 __x, _Float32 __y)
+  { return __builtin_isgreaterequal(__x, __y); }
+
+  constexpr bool
+  isless(_Float32 __x, _Float32 __y)
+  { return __builtin_isless(__x, __y); }
+
+  constexpr bool
+  islessequal(_Float32 __x, _Float32 __y)
+  { return __builtin_islessequal(__x, __y); }
+
+  constexpr bool
+  islessgreater(_Float32 __x, _Float32 __y)
+  { return __builtin_islessgreater(__x, __y); }
+
+  constexpr bool
+  isunordered(_Float32 __x, _Float32 __y)
+  { return __builtin_isunordered(__x, __y); }
+#endif
+
+#ifdef __STDCPP_FLOAT64_T__
+  constexpr int
+  fpclassify(_Float64 __x)
+  { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+				FP_SUBNORMAL, FP_ZERO, __x); }
+
+  constexpr bool
+  isfinite(_Float64 __x)
+  { return __builtin_isfinite(__x); }
+
+  constexpr bool
+  isinf(_Float64 __x)
+  { return __builtin_isinf(__x); }
+
+  constexpr bool
+  isnan(_Float64 __x)
+  { return __builtin_isnan(__x); }
+
+  constexpr bool
+  isnormal(_Float64 __x)
+  { return __builtin_isnormal(__x); }
+
+  constexpr bool
+  signbit(_Float64 __x)
+  { return __builtin_signbit(__x); }
+
+  constexpr bool
+  isgreater(_Float64 __x, _Float64 __y)
+  { return __builtin_isgreater(__x, __y); }
+
+  constexpr bool
+  isgreaterequal(_Float64 __x, _Float64 __y)
+  { return __builtin_isgreaterequal(__x, __y); }
+
+  constexpr bool
+  isless(_Float64 __x, _Float64 __y)
+  { return __builtin_isless(__x, __y); }
+
+  constexpr bool
+  islessequal(_Float64 __x, _Float64 __y)
+  { return __builtin_islessequal(__x, __y); }
+
+  constexpr bool
+  islessgreater(_Float64 __x, _Float64 __y)
+  { return __builtin_islessgreater(__x, __y); }
+
+  constexpr bool
+  isunordered(_Float64 __x, _Float64 __y)
+  { return __builtin_isunordered(__x, __y); }
+#endif
+
+#ifdef __STDCPP_FLOAT128_T__
+  constexpr int
+  fpclassify(_Float128 __x)
+  { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+				FP_SUBNORMAL, FP_ZERO, __x); }
+
+  constexpr bool
+  isfinite(_Float128 __x)
+  { return __builtin_isfinite(__x); }
+
+  constexpr bool
+  isinf(_Float128 __x)
+  { return __builtin_isinf(__x); }
+
+  constexpr bool
+  isnan(_Float128 __x)
+  { return __builtin_isnan(__x); }
+
+  constexpr bool
+  isnormal(_Float128 __x)
+  { return __builtin_isnormal(__x); }
+
+  constexpr bool
+  signbit(_Float128 __x)
+  { return __builtin_signbit(__x); }
+
+  constexpr bool
+  isgreater(_Float128 __x, _Float128 __y)
+  { return __builtin_isgreater(__x, __y); }
+
+  constexpr bool
+  isgreaterequal(_Float128 __x, _Float128 __y)
+  { return __builtin_isgreaterequal(__x, __y); }
+
+  constexpr bool
+  isless(_Float128 __x, _Float128 __y)
+  { return __builtin_isless(__x, __y); }
+
+  constexpr bool
+  islessequal(_Float128 __x, _Float128 __y)
+  { return __builtin_islessequal(__x, __y); }
+
+  constexpr bool
+  islessgreater(_Float128 __x, _Float128 __y)
+  { return __builtin_islessgreater(__x, __y); }
+
+  constexpr bool
+  isunordered(_Float128 __x, _Float128 __y)
+  { return __builtin_isunordered(__x, __y); }
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+  constexpr int
+  fpclassify(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+				FP_SUBNORMAL, FP_ZERO, __x); }
+
+  constexpr bool
+  isfinite(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_isfinite(__x); }
+
+  constexpr bool
+  isinf(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_isinf(__x); }
+
+  constexpr bool
+  isnan(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_isnan(__x); }
+
+  constexpr bool
+  isnormal(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_isnormal(__x); }
+
+  constexpr bool
+  signbit(__gnu_cxx::__bfloat16_t __x)
+  { return __builtin_signbit(__x); }
+
+  constexpr bool
+  isgreater(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_isgreater(__x, __y); }
+
+  constexpr bool
+  isgreaterequal(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_isgreaterequal(__x, __y); }
+
+  constexpr bool
+  isless(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_isless(__x, __y); }
+
+  constexpr bool
+  islessequal(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_islessequal(__x, __y); }
+
+  constexpr bool
+  islessgreater(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_islessgreater(__x, __y); }
+
+  constexpr bool
+  isunordered(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __builtin_isunordered(__x, __y); }
+#endif
+
 #endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */
 #endif /* _GLIBCXX_USE_C99_MATH */
 
@@ -1843,6 +2657,811 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return __builtin_trunc(__x); }
 #endif
 
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  constexpr _Float16
+  acosh(_Float16 __x)
+  { return _Float16(__builtin_acoshf(__x)); }
+
+  constexpr _Float16
+  asinh(_Float16 __x)
+  { return _Float16(__builtin_asinhf(__x)); }
+
+  constexpr _Float16
+  atanh(_Float16 __x)
+  { return _Float16(__builtin_atanhf(__x)); }
+
+  constexpr _Float16
+  cbrt(_Float16 __x)
+  { return _Float16(__builtin_cbrtf(__x)); }
+
+  constexpr _Float16
+  copysign(_Float16 __x, _Float16 __y)
+  { return __builtin_copysignf16(__x, __y); }
+
+  constexpr _Float16
+  erf(_Float16 __x)
+  { return _Float16(__builtin_erff(__x)); }
+
+  constexpr _Float16
+  erfc(_Float16 __x)
+  { return _Float16(__builtin_erfcf(__x)); }
+
+  constexpr _Float16
+  exp2(_Float16 __x)
+  { return _Float16(__builtin_exp2f(__x)); }
+
+  constexpr _Float16
+  expm1(_Float16 __x)
+  { return _Float16(__builtin_expm1f(__x)); }
+
+  constexpr _Float16
+  fdim(_Float16 __x, _Float16 __y)
+  { return _Float16(__builtin_fdimf(__x, __y)); }
+
+  constexpr _Float16
+  fma(_Float16 __x, _Float16 __y, _Float16 __z)
+  { return _Float16(__builtin_fmaf(__x, __y, __z)); }
+
+  constexpr _Float16
+  fmax(_Float16 __x, _Float16 __y)
+  { return _Float16(__builtin_fmaxf(__x, __y)); }
+
+  constexpr _Float16
+  fmin(_Float16 __x, _Float16 __y)
+  { return _Float16(__builtin_fminf(__x, __y)); }
+
+  constexpr _Float16
+  hypot(_Float16 __x, _Float16 __y)
+  { return _Float16(__builtin_hypotf(__x, __y)); }
+
+  constexpr int
+  ilogb(_Float16 __x)
+  { return _Float16(__builtin_ilogbf(__x)); }
+
+  constexpr _Float16
+  lgamma(_Float16 __x)
+  { return _Float16(__builtin_lgammaf(__x)); }
+
+  constexpr long long
+  llrint(_Float16 __x)
+  { return _Float16(__builtin_llrintf(__x)); }
+
+  constexpr long long
+  llround(_Float16 __x)
+  { return _Float16(__builtin_llroundf(__x)); }
+
+  constexpr _Float16
+  log1p(_Float16 __x)
+  { return _Float16(__builtin_log1pf(__x)); }
+
+  // DR 568.
+  constexpr _Float16
+  log2(_Float16 __x)
+  { return _Float16(__builtin_log2f(__x)); }
+
+  constexpr _Float16
+  logb(_Float16 __x)
+  { return _Float16(__builtin_logbf(__x)); }
+
+  constexpr long
+  lrint(_Float16 __x)
+  { return _Float16(__builtin_lrintf(__x)); }
+
+  constexpr long
+  lround(_Float16 __x)
+  { return _Float16(__builtin_lroundf(__x)); }
+
+  constexpr _Float16
+  nearbyint(_Float16 __x)
+  { return _Float16(__builtin_nearbyintf(__x)); }
+
+  // nextafter not implemented so far.
+
+  constexpr _Float16
+  remainder(_Float16 __x, _Float16 __y)
+  { return _Float16(__builtin_remainderf(__x, __y)); }
+
+  inline _Float16
+  remquo(_Float16 __x, _Float16 __y, int* __pquo)
+  { return _Float16(__builtin_remquof(__x, __y, __pquo)); }
+
+  constexpr _Float16
+  rint(_Float16 __x)
+  { return _Float16(__builtin_rintf(__x)); }
+
+  constexpr _Float16
+  round(_Float16 __x)
+  { return _Float16(__builtin_roundf(__x)); }
+
+  constexpr _Float16
+  scalbln(_Float16 __x, long __ex)
+  { return _Float16(__builtin_scalblnf(__x, __ex)); }
+
+  constexpr _Float16
+  scalbn(_Float16 __x, int __ex)
+  { return _Float16(__builtin_scalbnf(__x, __ex)); }
+
+  constexpr _Float16
+  tgamma(_Float16 __x)
+  { return _Float16(__builtin_tgammaf(__x)); }
+
+  constexpr _Float16
+  trunc(_Float16 __x)
+  { return _Float16(__builtin_truncf(__x)); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  constexpr _Float32
+  acosh(_Float32 __x)
+  { return __builtin_acoshf(__x); }
+
+  constexpr _Float32
+  asinh(_Float32 __x)
+  { return __builtin_asinhf(__x); }
+
+  constexpr _Float32
+  atanh(_Float32 __x)
+  { return __builtin_atanhf(__x); }
+
+  constexpr _Float32
+  cbrt(_Float32 __x)
+  { return __builtin_cbrtf(__x); }
+
+  constexpr _Float32
+  copysign(_Float32 __x, _Float32 __y)
+  { return __builtin_copysignf(__x, __y); }
+
+  constexpr _Float32
+  erf(_Float32 __x)
+  { return __builtin_erff(__x); }
+
+  constexpr _Float32
+  erfc(_Float32 __x)
+  { return __builtin_erfcf(__x); }
+
+  constexpr _Float32
+  exp2(_Float32 __x)
+  { return __builtin_exp2f(__x); }
+
+  constexpr _Float32
+  expm1(_Float32 __x)
+  { return __builtin_expm1f(__x); }
+
+  constexpr _Float32
+  fdim(_Float32 __x, _Float32 __y)
+  { return __builtin_fdimf(__x, __y); }
+
+  constexpr _Float32
+  fma(_Float32 __x, _Float32 __y, _Float32 __z)
+  { return __builtin_fmaf(__x, __y, __z); }
+
+  constexpr _Float32
+  fmax(_Float32 __x, _Float32 __y)
+  { return __builtin_fmaxf(__x, __y); }
+
+  constexpr _Float32
+  fmin(_Float32 __x, _Float32 __y)
+  { return __builtin_fminf(__x, __y); }
+
+  constexpr _Float32
+  hypot(_Float32 __x, _Float32 __y)
+  { return __builtin_hypotf(__x, __y); }
+
+  constexpr int
+  ilogb(_Float32 __x)
+  { return __builtin_ilogbf(__x); }
+
+  constexpr _Float32
+  lgamma(_Float32 __x)
+  { return __builtin_lgammaf(__x); }
+
+  constexpr long long
+  llrint(_Float32 __x)
+  { return __builtin_llrintf(__x); }
+
+  constexpr long long
+  llround(_Float32 __x)
+  { return __builtin_llroundf(__x); }
+
+  constexpr _Float32
+  log1p(_Float32 __x)
+  { return __builtin_log1pf(__x); }
+
+  // DR 568.
+  constexpr _Float32
+  log2(_Float32 __x)
+  { return __builtin_log2f(__x); }
+
+  constexpr _Float32
+  logb(_Float32 __x)
+  { return __builtin_logbf(__x); }
+
+  constexpr long
+  lrint(_Float32 __x)
+  { return __builtin_lrintf(__x); }
+
+  constexpr long
+  lround(_Float32 __x)
+  { return __builtin_lroundf(__x); }
+
+  constexpr _Float32
+  nearbyint(_Float32 __x)
+  { return __builtin_nearbyintf(__x); }
+
+  constexpr _Float32
+  nextafter(_Float32 __x, _Float32 __y)
+  { return __builtin_nextafterf(__x, __y); }
+
+  constexpr _Float32
+  remainder(_Float32 __x, _Float32 __y)
+  { return __builtin_remainderf(__x, __y); }
+
+  inline _Float32
+  remquo(_Float32 __x, _Float32 __y, int* __pquo)
+  { return __builtin_remquof(__x, __y, __pquo); }
+
+  constexpr _Float32
+  rint(_Float32 __x)
+  { return __builtin_rintf(__x); }
+
+  constexpr _Float32
+  round(_Float32 __x)
+  { return __builtin_roundf(__x); }
+
+  constexpr _Float32
+  scalbln(_Float32 __x, long __ex)
+  { return __builtin_scalblnf(__x, __ex); }
+
+  constexpr _Float32
+  scalbn(_Float32 __x, int __ex)
+  { return __builtin_scalbnf(__x, __ex); }
+
+  constexpr _Float32
+  tgamma(_Float32 __x)
+  { return __builtin_tgammaf(__x); }
+
+  constexpr _Float32
+  trunc(_Float32 __x)
+  { return __builtin_truncf(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  constexpr _Float64
+  acosh(_Float64 __x)
+  { return __builtin_acosh(__x); }
+
+  constexpr _Float64
+  asinh(_Float64 __x)
+  { return __builtin_asinh(__x); }
+
+  constexpr _Float64
+  atanh(_Float64 __x)
+  { return __builtin_atanh(__x); }
+
+  constexpr _Float64
+  cbrt(_Float64 __x)
+  { return __builtin_cbrt(__x); }
+
+  constexpr _Float64
+  copysign(_Float64 __x, _Float64 __y)
+  { return __builtin_copysign(__x, __y); }
+
+  constexpr _Float64
+  erf(_Float64 __x)
+  { return __builtin_erf(__x); }
+
+  constexpr _Float64
+  erfc(_Float64 __x)
+  { return __builtin_erfc(__x); }
+
+  constexpr _Float64
+  exp2(_Float64 __x)
+  { return __builtin_exp2(__x); }
+
+  constexpr _Float64
+  expm1(_Float64 __x)
+  { return __builtin_expm1(__x); }
+
+  constexpr _Float64
+  fdim(_Float64 __x, _Float64 __y)
+  { return __builtin_fdim(__x, __y); }
+
+  constexpr _Float64
+  fma(_Float64 __x, _Float64 __y, _Float64 __z)
+  { return __builtin_fma(__x, __y, __z); }
+
+  constexpr _Float64
+  fmax(_Float64 __x, _Float64 __y)
+  { return __builtin_fmax(__x, __y); }
+
+  constexpr _Float64
+  fmin(_Float64 __x, _Float64 __y)
+  { return __builtin_fmin(__x, __y); }
+
+  constexpr _Float64
+  hypot(_Float64 __x, _Float64 __y)
+  { return __builtin_hypot(__x, __y); }
+
+  constexpr int
+  ilogb(_Float64 __x)
+  { return __builtin_ilogb(__x); }
+
+  constexpr _Float64
+  lgamma(_Float64 __x)
+  { return __builtin_lgamma(__x); }
+
+  constexpr long long
+  llrint(_Float64 __x)
+  { return __builtin_llrint(__x); }
+
+  constexpr long long
+  llround(_Float64 __x)
+  { return __builtin_llround(__x); }
+
+  constexpr _Float64
+  log1p(_Float64 __x)
+  { return __builtin_log1p(__x); }
+
+  // DR 568.
+  constexpr _Float64
+  log2(_Float64 __x)
+  { return __builtin_log2(__x); }
+
+  constexpr _Float64
+  logb(_Float64 __x)
+  { return __builtin_logb(__x); }
+
+  constexpr long
+  lrint(_Float64 __x)
+  { return __builtin_lrint(__x); }
+
+  constexpr long
+  lround(_Float64 __x)
+  { return __builtin_lround(__x); }
+
+  constexpr _Float64
+  nearbyint(_Float64 __x)
+  { return __builtin_nearbyint(__x); }
+
+  constexpr _Float64
+  nextafter(_Float64 __x, _Float64 __y)
+  { return __builtin_nextafter(__x, __y); }
+
+  constexpr _Float64
+  remainder(_Float64 __x, _Float64 __y)
+  { return __builtin_remainder(__x, __y); }
+
+  inline _Float64
+  remquo(_Float64 __x, _Float64 __y, int* __pquo)
+  { return __builtin_remquo(__x, __y, __pquo); }
+
+  constexpr _Float64
+  rint(_Float64 __x)
+  { return __builtin_rint(__x); }
+
+  constexpr _Float64
+  round(_Float64 __x)
+  { return __builtin_round(__x); }
+
+  constexpr _Float64
+  scalbln(_Float64 __x, long __ex)
+  { return __builtin_scalbln(__x, __ex); }
+
+  constexpr _Float64
+  scalbn(_Float64 __x, int __ex)
+  { return __builtin_scalbn(__x, __ex); }
+
+  constexpr _Float64
+  tgamma(_Float64 __x)
+  { return __builtin_tgamma(__x); }
+
+  constexpr _Float64
+  trunc(_Float64 __x)
+  { return __builtin_trunc(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+  constexpr _Float128
+  acosh(_Float128 __x)
+  { return __builtin_acoshl(__x); }
+
+  constexpr _Float128
+  asinh(_Float128 __x)
+  { return __builtin_asinhl(__x); }
+
+  constexpr _Float128
+  atanh(_Float128 __x)
+  { return __builtin_atanhl(__x); }
+
+  constexpr _Float128
+  cbrt(_Float128 __x)
+  { return __builtin_cbrtl(__x); }
+
+  constexpr _Float128
+  copysign(_Float128 __x, _Float128 __y)
+  { return __builtin_copysignl(__x, __y); }
+
+  constexpr _Float128
+  erf(_Float128 __x)
+  { return __builtin_erfl(__x); }
+
+  constexpr _Float128
+  erfc(_Float128 __x)
+  { return __builtin_erfcl(__x); }
+
+  constexpr _Float128
+  exp2(_Float128 __x)
+  { return __builtin_exp2l(__x); }
+
+  constexpr _Float128
+  expm1(_Float128 __x)
+  { return __builtin_expm1l(__x); }
+
+  constexpr _Float128
+  fdim(_Float128 __x, _Float128 __y)
+  { return __builtin_fdiml(__x, __y); }
+
+  constexpr _Float128
+  fma(_Float128 __x, _Float128 __y, _Float128 __z)
+  { return __builtin_fmal(__x, __y, __z); }
+
+  constexpr _Float128
+  fmax(_Float128 __x, _Float128 __y)
+  { return __builtin_fmaxl(__x, __y); }
+
+  constexpr _Float128
+  fmin(_Float128 __x, _Float128 __y)
+  { return __builtin_fminl(__x, __y); }
+
+  constexpr _Float128
+  hypot(_Float128 __x, _Float128 __y)
+  { return __builtin_hypotl(__x, __y); }
+
+  constexpr int
+  ilogb(_Float128 __x)
+  { return __builtin_ilogbl(__x); }
+
+  constexpr _Float128
+  lgamma(_Float128 __x)
+  { return __builtin_lgammal(__x); }
+
+  constexpr long long
+  llrint(_Float128 __x)
+  { return __builtin_llrintl(__x); }
+
+  constexpr long long
+  llround(_Float128 __x)
+  { return __builtin_llroundl(__x); }
+
+  constexpr _Float128
+  log1p(_Float128 __x)
+  { return __builtin_log1pl(__x); }
+
+  // DR 568.
+  constexpr _Float128
+  log2(_Float128 __x)
+  { return __builtin_log2l(__x); }
+
+  constexpr _Float128
+  logb(_Float128 __x)
+  { return __builtin_logbl(__x); }
+
+  constexpr long
+  lrint(_Float128 __x)
+  { return __builtin_lrintl(__x); }
+
+  constexpr long
+  lround(_Float128 __x)
+  { return __builtin_lroundl(__x); }
+
+  constexpr _Float128
+  nearbyint(_Float128 __x)
+  { return __builtin_nearbyintl(__x); }
+
+  constexpr _Float128
+  nextafter(_Float128 __x, _Float128 __y)
+  { return __builtin_nextafterl(__x, __y); }
+
+  constexpr _Float128
+  remainder(_Float128 __x, _Float128 __y)
+  { return __builtin_remainderl(__x, __y); }
+
+  inline _Float128
+  remquo(_Float128 __x, _Float128 __y, int* __pquo)
+  { return __builtin_remquol(__x, __y, __pquo); }
+
+  constexpr _Float128
+  rint(_Float128 __x)
+  { return __builtin_rintl(__x); }
+
+  constexpr _Float128
+  round(_Float128 __x)
+  { return __builtin_roundl(__x); }
+
+  constexpr _Float128
+  scalbln(_Float128 __x, long __ex)
+  { return __builtin_scalblnl(__x, __ex); }
+
+  constexpr _Float128
+  scalbn(_Float128 __x, int __ex)
+  { return __builtin_scalbnl(__x, __ex); }
+
+  constexpr _Float128
+  tgamma(_Float128 __x)
+  { return __builtin_tgammal(__x); }
+
+  constexpr _Float128
+  trunc(_Float128 __x)
+  { return __builtin_truncl(__x); }
+#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
+  constexpr _Float128
+  acosh(_Float128 __x)
+  { return __builtin_acoshf128(__x); }
+
+  constexpr _Float128
+  asinh(_Float128 __x)
+  { return __builtin_asinhf128(__x); }
+
+  constexpr _Float128
+  atanh(_Float128 __x)
+  { return __builtin_atanhf128(__x); }
+
+  constexpr _Float128
+  cbrt(_Float128 __x)
+  { return __builtin_cbrtf128(__x); }
+
+  constexpr _Float128
+  copysign(_Float128 __x, _Float128 __y)
+  { return __builtin_copysignf128(__x, __y); }
+
+  constexpr _Float128
+  erf(_Float128 __x)
+  { return __builtin_erff128(__x); }
+
+  constexpr _Float128
+  erfc(_Float128 __x)
+  { return __builtin_erfcf128(__x); }
+
+  constexpr _Float128
+  exp2(_Float128 __x)
+  { return __builtin_exp2f128(__x); }
+
+  constexpr _Float128
+  expm1(_Float128 __x)
+  { return __builtin_expm1f128(__x); }
+
+  constexpr _Float128
+  fdim(_Float128 __x, _Float128 __y)
+  { return __builtin_fdimf128(__x, __y); }
+
+  constexpr _Float128
+  fma(_Float128 __x, _Float128 __y, _Float128 __z)
+  { return __builtin_fmaf128(__x, __y, __z); }
+
+  constexpr _Float128
+  fmax(_Float128 __x, _Float128 __y)
+  { return __builtin_fmaxf128(__x, __y); }
+
+  constexpr _Float128
+  fmin(_Float128 __x, _Float128 __y)
+  { return __builtin_fminf128(__x, __y); }
+
+  constexpr _Float128
+  hypot(_Float128 __x, _Float128 __y)
+  { return __builtin_hypotf128(__x, __y); }
+
+  constexpr int
+  ilogb(_Float128 __x)
+  { return __builtin_ilogbf128(__x); }
+
+  constexpr _Float128
+  lgamma(_Float128 __x)
+  { return __builtin_lgammaf128(__x); }
+
+  constexpr long long
+  llrint(_Float128 __x)
+  { return __builtin_llrintf128(__x); }
+
+  constexpr long long
+  llround(_Float128 __x)
+  { return __builtin_llroundf128(__x); }
+
+  constexpr _Float128
+  log1p(_Float128 __x)
+  { return __builtin_log1pf128(__x); }
+
+  // DR 568.
+  constexpr _Float128
+  log2(_Float128 __x)
+  { return __builtin_log2f128(__x); }
+
+  constexpr _Float128
+  logb(_Float128 __x)
+  { return __builtin_logbf128(__x); }
+
+  constexpr long
+  lrint(_Float128 __x)
+  { return __builtin_lrintf128(__x); }
+
+  constexpr long
+  lround(_Float128 __x)
+  { return __builtin_lroundf128(__x); }
+
+  constexpr _Float128
+  nearbyint(_Float128 __x)
+  { return __builtin_nearbyintf128(__x); }
+
+  constexpr _Float128
+  nextafter(_Float128 __x, _Float128 __y)
+  { return __builtin_nextafterf128(__x, __y); }
+
+  constexpr _Float128
+  remainder(_Float128 __x, _Float128 __y)
+  { return __builtin_remainderf128(__x, __y); }
+
+  inline _Float128
+  remquo(_Float128 __x, _Float128 __y, int* __pquo)
+  { return __builtin_remquof128(__x, __y, __pquo); }
+
+  constexpr _Float128
+  rint(_Float128 __x)
+  { return __builtin_rintf128(__x); }
+
+  constexpr _Float128
+  round(_Float128 __x)
+  { return __builtin_roundf128(__x); }
+
+  constexpr _Float128
+  scalbln(_Float128 __x, long __ex)
+  { return __builtin_scalblnf128(__x, __ex); }
+
+  constexpr _Float128
+  scalbn(_Float128 __x, int __ex)
+  { return __builtin_scalbnf128(__x, __ex); }
+
+  constexpr _Float128
+  tgamma(_Float128 __x)
+  { return __builtin_tgammaf128(__x); }
+
+  constexpr _Float128
+  trunc(_Float128 __x)
+  { return __builtin_truncf128(__x); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  constexpr __gnu_cxx::__bfloat16_t
+  acosh(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_acoshf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  asinh(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_asinhf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  atanh(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_atanhf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  cbrt(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_cbrtf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  copysign(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_copysignf(__x, __y)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  erf(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_erff(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  erfc(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_erfcf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  exp2(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_exp2f(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  expm1(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_expm1f(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  fdim(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_fdimf(__x, __y)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  fma(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y, __gnu_cxx::__bfloat16_t __z)
+  { return __gnu_cxx::__bfloat16_t(__builtin_fmaf(__x, __y, __z)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  fmax(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_fmaxf(__x, __y)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  fmin(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_fminf(__x, __y)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  hypot(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_hypotf(__x, __y)); }
+
+  constexpr int
+  ilogb(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_ilogbf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  lgamma(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_lgammaf(__x)); }
+
+  constexpr long long
+  llrint(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_llrintf(__x)); }
+
+  constexpr long long
+  llround(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_llroundf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  log1p(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_log1pf(__x)); }
+
+  // DR 568.
+  constexpr __gnu_cxx::__bfloat16_t
+  log2(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_log2f(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  logb(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_logbf(__x)); }
+
+  constexpr long
+  lrint(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_lrintf(__x)); }
+
+  constexpr long
+  lround(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_lroundf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  nearbyint(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_nearbyintf(__x)); }
+
+  // nextafter not implemented so far.
+
+  constexpr __gnu_cxx::__bfloat16_t
+  remainder(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+  { return __gnu_cxx::__bfloat16_t(__builtin_remainderf(__x, __y)); }
+
+  inline __gnu_cxx::__bfloat16_t
+  remquo(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y, int* __pquo)
+  { return __gnu_cxx::__bfloat16_t(__builtin_remquof(__x, __y, __pquo)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  rint(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_rintf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  round(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_roundf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  scalbln(__gnu_cxx::__bfloat16_t __x, long __ex)
+  { return __gnu_cxx::__bfloat16_t(__builtin_scalblnf(__x, __ex)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  scalbn(__gnu_cxx::__bfloat16_t __x, int __ex)
+  { return __gnu_cxx::__bfloat16_t(__builtin_scalbnf(__x, __ex)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  tgamma(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_tgammaf(__x)); }
+
+  constexpr __gnu_cxx::__bfloat16_t
+  trunc(__gnu_cxx::__bfloat16_t __x)
+  { return __gnu_cxx::__bfloat16_t(__builtin_truncf(__x)); }
+#endif
+
+
 #endif // _GLIBCXX_USE_C99_MATH_TR1
 #endif // C++11
 
@@ -1885,6 +3504,39 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using __type = __gnu_cxx::__promoted_t<_Tp, _Up, _Vp>;
       return std::__hypot3<__type>(__x, __y, __z);
     }
+
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _Float16
+  hypot(_Float16 __x, _Float16 __y, _Float16 __z)
+  { return std::__hypot3<_Float16>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _Float32
+  hypot(_Float32 __x, _Float32 __y, _Float32 __z)
+  { return std::__hypot3<_Float32>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  inline _Float64
+  hypot(_Float64 __x, _Float64 __y, _Float64 __z)
+  { return std::__hypot3<_Float64>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) \
+    && (defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128) \
+	|| defined(_GLIBCXX_HAVE_FLOAT128_MATH))
+  inline _Float128
+  hypot(_Float128 __x, _Float128 __y, _Float128 __z)
+  { return std::__hypot3<_Float128>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline __gnu_cxx::__bfloat16_t
+  hypot(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y, __gnu_cxx::__bfloat16_t __z)
+  { return std::__hypot3<__gnu_cxx::__bfloat16_t>(__x, __y, __z); }
+#endif
+
 #endif // C++17
 
 #if __cplusplus >= 202002L
@@ -1928,6 +3580,39 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using __type = __gnu_cxx::__promoted_t<_Tp, _Up, _Vp>;
       return std::__lerp<__type>(__x, __y, __z);
     }
+
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _Float16
+  lerp(_Float16 __x, _Float16 __y, _Float16 __z) noexcept
+  { return std::__lerp<_Float16>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline _Float32
+  lerp(_Float32 __x, _Float32 __y, _Float32 __z) noexcept
+  { return std::__lerp<_Float32>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  inline _Float64
+  lerp(_Float64 __x, _Float64 __y, _Float64 __z) noexcept
+  { return std::__lerp<_Float64>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) \
+    && (defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128) \
+	|| defined(_GLIBCXX_HAVE_FLOAT128_MATH))
+  inline _Float128
+  lerp(_Float128 __x, _Float128 __y, _Float128 __z) noexcept
+  { return std::__lerp<_Float128>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  inline __gnu_cxx::__bfloat16_t
+  lerp(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y, __gnu_cxx::__bfloat16_t __z) noexcept
+  { return std::__lerp<__gnu_cxx::__bfloat16_t>(__x, __y, __z); }
+#endif
+
 #endif // C++20
 
 _GLIBCXX_END_NAMESPACE_VERSION
--- libstdc++-v3/include/ext/type_traits.h.jj	2022-01-11 22:31:41.519756736 +0100
+++ libstdc++-v3/include/ext/type_traits.h	2022-10-15 11:08:49.897857492 +0200
@@ -190,6 +190,36 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __promote<float>
     { typedef float __type; };
 
+#ifdef __STDCPP_FLOAT16_T__
+  template<>
+    struct __promote<_Float16>
+    { typedef _Float16 __type; };
+#endif
+
+#ifdef __STDCPP_FLOAT32_T__
+  template<>
+    struct __promote<_Float32>
+    { typedef _Float32 __type; };
+#endif
+
+#ifdef __STDCPP_FLOAT64_T__
+  template<>
+    struct __promote<_Float64>
+    { typedef _Float64 __type; };
+#endif
+
+#ifdef __STDCPP_FLOAT128_T__
+  template<>
+    struct __promote<_Float128>
+    { typedef _Float128 __type; };
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+  template<>
+    struct __promote<__gnu_cxx::__bfloat16_t>
+    { typedef __gnu_cxx::__bfloat16_t __type; };
+#endif
+
 #if __cpp_fold_expressions
 
   template<typename... _Tp>
--- libstdc++-v3/include/Makefile.am.jj	2022-10-03 22:45:46.092435137 +0200
+++ libstdc++-v3/include/Makefile.am	2022-10-14 22:32:55.413346435 +0200
@@ -95,6 +95,7 @@  std_headers = \
 	${std_srcdir}/stack \
 	${std_srcdir}/stacktrace \
 	${std_srcdir}/stdexcept \
+	${std_srcdir}/stdfloat \
 	${std_srcdir}/stop_token \
 	${std_srcdir}/streambuf \
 	${std_srcdir}/string \
--- libstdc++-v3/include/Makefile.in.jj	2022-10-11 22:35:26.387468956 +0200
+++ libstdc++-v3/include/Makefile.in	2022-10-14 22:32:55.413346435 +0200
@@ -452,6 +452,7 @@  std_freestanding = \
 @GLIBCXX_HOSTED_TRUE@	${std_srcdir}/stack \
 @GLIBCXX_HOSTED_TRUE@	${std_srcdir}/stacktrace \
 @GLIBCXX_HOSTED_TRUE@	${std_srcdir}/stdexcept \
+@GLIBCXX_HOSTED_TRUE@	${std_srcdir}/stdfloat \
 @GLIBCXX_HOSTED_TRUE@	${std_srcdir}/stop_token \
 @GLIBCXX_HOSTED_TRUE@	${std_srcdir}/streambuf \
 @GLIBCXX_HOSTED_TRUE@	${std_srcdir}/string \
--- libstdc++-v3/include/precompiled/stdc++.h.jj	2022-10-03 22:45:46.100435029 +0200
+++ libstdc++-v3/include/precompiled/stdc++.h	2022-10-14 22:32:55.413346435 +0200
@@ -228,6 +228,7 @@ 
 # include <stacktrace>
 #endif
 #include <stdatomic.h>
+#include <stdfloat>
 #endif
 
 #endif // HOSTED
--- libstdc++-v3/config/os/gnu-linux/os_defines.h.jj	2022-01-11 22:31:41.469757439 +0100
+++ libstdc++-v3/config/os/gnu-linux/os_defines.h	2022-10-14 22:32:55.414346421 +0200
@@ -49,6 +49,17 @@ 
 // version dynamically in case it has changed since libstdc++ was configured.
 #define _GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC __GLIBC_PREREQ(2,23)
 
+// Glibc 2.26 on i?86/x86-64/ia64/ppc64le added *f128 support.
+// Glibc 2.27 added it also on many other arches but those have IEEE quad
+// long double.
+#if __GLIBC_PREREQ(2, 26) \
+    && (defined(__i386__) || defined(__x86_64__) || defined (__ia64__) \
+	|| (defined(__powerpc__) && defined(_ARCH_PWR8) \
+	    && defined(__LITTLE_ENDIAN__) && (_CALL_ELF == 2) \
+	    && defined(__FLOAT128__)))
+# define _GLIBCXX_HAVE_FLOAT128_MATH 1
+#endif
+
 #if __GLIBC_PREREQ(2, 27)
 // Since glibc 2.27 pthread_self() is usable without linking to libpthread.
 # define _GLIBCXX_NATIVE_THREAD_ID pthread_self()
--- libstdc++-v3/testsuite/18_support/headers/stdfloat/types_std.cc.jj	2022-10-14 22:32:55.414346421 +0200
+++ libstdc++-v3/testsuite/18_support/headers/stdfloat/types_std.cc	2022-10-14 22:32:55.414346421 +0200
@@ -0,0 +1,40 @@ 
+// { dg-options "-std=gnu++2b" }
+// { dg-do compile { target c++23 } }
+
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This 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 General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <stdfloat>
+
+namespace gnu
+{
+#if defined(__STDCPP_FLOAT16_T__)
+  typedef std::float16_t t1;
+#endif
+#if defined(__STDCPP_FLOAT32_T__)
+  typedef std::float32_t t2;
+#endif
+#if defined(__STDCPP_FLOAT64_T__)
+  typedef std::float64_t t3;
+#endif
+#if defined(__STDCPP_FLOAT128_T__)
+  typedef std::float128_t t4;
+#endif
+#if defined(__STDCPP_BFLOAT16_T__)
+  typedef std::bfloat16_t t5;
+#endif
+}
--- libstdc++-v3/testsuite/18_support/headers/limits/synopsis_cxx23.cc.jj	2022-10-14 22:32:55.415346407 +0200
+++ libstdc++-v3/testsuite/18_support/headers/limits/synopsis_cxx23.cc	2022-10-14 22:32:55.415346407 +0200
@@ -0,0 +1,43 @@ 
+// { dg-options "-std=gnu++2b" }
+// { dg-do compile { target c++23 } }
+// { dg-require-normal-namespace "" }
+
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This 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 General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <limits>
+#include <stdfloat>
+
+namespace std {
+  template<class T> class numeric_limits;
+
+#if defined(__STDCPP_FLOAT16_T__)
+  template<> class numeric_limits<float16_t>;
+#endif
+#if defined(__STDCPP_FLOAT32_T__)
+  template<> class numeric_limits<float32_t>;
+#endif
+#if defined(__STDCPP_FLOAT64_T__)
+  template<> class numeric_limits<float64_t>;
+#endif
+#if defined(__STDCPP_FLOAT128_T__)
+  template<> class numeric_limits<float128_t>;
+#endif
+#if defined(__STDCPP_BFLOAT16_T__)
+  template<> class numeric_limits<bfloat16_t>;
+#endif
+}
--- libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c++23.cc.jj	2022-10-14 22:32:55.415346407 +0200
+++ libstdc++-v3/testsuite/26_numerics/headers/cmath/c99_classification_macros_c++23.cc	2022-10-14 22:32:55.415346407 +0200
@@ -0,0 +1,96 @@ 
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This 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 General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do link { target c++23 } }
+// { dg-excess-errors "" { target uclibc } }
+
+#include <cmath>
+#include <stdfloat>
+
+void fpclassify() { }
+
+void isfinite() { }
+
+void isinf() { }
+
+void isnan() { }
+
+void isnormal() { }
+
+void signbit() { }
+
+void isgreater() { }
+
+void isgreaterequal() { }
+
+void isless() { }
+
+void islessequal() { }
+
+void islessgreater() { }
+
+void isunordered() { }
+
+#if _GLIBCXX_USE_C99_MATH
+template <typename _Tp, typename _Up = _Tp>
+  void test_c99_classify()
+  {
+    typedef _Tp fp_type_one;
+    typedef _Up fp_type_two;
+    fp_type_one f1 = _Tp(1.0);
+    fp_type_two f2 = _Up(3.0);
+    int resi;
+    volatile bool res;
+
+    resi = std::fpclassify(f1);
+    res = std::isfinite(f2);
+    res = std::isinf(f1);
+    res = std::isnan(f2);
+    res = std::isnormal(f1);
+    res = std::signbit(f2);
+    res = std::isgreater(f1, f2);
+    res = std::isgreaterequal(f1, f2);
+    res = std::isless(f1, f2);
+    res = std::islessequal(f1,f2);
+    res = std::islessgreater(f1, f2);
+    res = std::isunordered(f1, f2);
+    resi = resi; // Suppress unused warning.
+    res = res;
+  }
+#endif
+
+int main()
+{
+#if _GLIBCXX_USE_C99_MATH
+#ifdef __STDCPP_FLOAT16_T__
+  test_c99_classify<std::float16_t>();
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+  test_c99_classify<std::float32_t>();
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+  test_c99_classify<std::float64_t>();
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+  test_c99_classify<std::float128_t>();
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+  test_c99_classify<std::bfloat16_t>();
+#endif
+#endif
+  return 0;
+}
--- libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_std_c++23.cc.jj	2022-10-14 22:32:55.415346407 +0200
+++ libstdc++-v3/testsuite/26_numerics/headers/cmath/functions_std_c++23.cc	2022-10-15 11:43:08.107500180 +0200
@@ -0,0 +1,146 @@ 
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This 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 General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do link { target c++23 } }
+
+#include <stdfloat>
+#include <cmath>
+
+template <typename T>
+__attribute__((__noipa__)) void
+test_functions (T *p, int *q, long int *r, long long int *s)
+{
+  p[0] = std::acos (p[0]);
+  p[1] = std::asin (p[1]);
+  p[2] = std::atan (p[2]);
+  p[3] = std::cos (p[3]);
+  p[4] = std::sin (p[4]);
+  p[5] = std::tan (p[5]);
+  p[6] = std::acosh (p[6]);
+  p[7] = std::asinh (p[7]);
+  p[8] = std::atanh (p[8]);
+  p[9] = std::cosh (p[9]);
+  p[10] = std::sinh (p[10]);
+  p[11] = std::tanh (p[11]);
+  p[12] = std::exp (p[12]);
+  p[13] = std::exp2 (p[13]);
+  p[14] = std::expm1 (p[14]);
+  p[15] = std::log (p[15]);
+  p[16] = std::log10 (p[16]);
+  p[17] = std::log1p (p[17]);
+  p[18] = std::log2 (p[18]);
+  p[19] = std::logb (p[19]);
+  p[20] = std::cbrt (p[20]);
+  p[21] = std::fabs (p[21]);
+  p[22] = std::sqrt (p[22]);
+  p[23] = std::erf (p[23]);
+  p[24] = std::erfc (p[24]);
+  p[25] = std::lgamma (p[25]);
+  p[26] = std::tgamma (p[26]);
+  p[27] = std::ceil (p[27]);
+  p[28] = std::floor (p[28]);
+  p[29] = std::nearbyint (p[29]);
+  p[30] = std::rint (p[30]);
+  p[31] = std::round (p[31]);
+  p[32] = std::trunc (p[32]);
+  p[33] = std::atan2 (p[33], p[100]);
+  p[34] = std::hypot (p[34], p[101]);
+  p[35] = std::pow (p[35], p[102]);
+  p[36] = std::fmod (p[36], p[103]);
+  p[37] = std::remainder (p[37], p[104]);
+  p[38] = std::copysign (p[38], p[105]);
+//  p[39] = std::nextafter (p[39], p[106]);
+  p[40] = std::fdim (p[40], p[107]);
+  p[41] = std::fmax (p[41], p[108]);
+  p[42] = std::fmin (p[42], p[109]);
+  p[43] = std::atan2 (p[43], p[110]);
+  p[44] = std::frexp (p[44], q + 0);
+  q[1] = std::ilogb (p[45]);
+  p[46] = std::ldexp (p[46], q[2]);
+  p[47] = std::modf (p[47], p + 111);
+  p[48] = std::scalbn (p[48], q[3]);
+  p[49] = std::scalbln (p[49], r[0]);
+  p[50] = std::hypot (p[50], p[111], p[112]);
+  r[1] = std::lrint (p[51]);
+  s[0] = std::llrint (p[52]);
+  r[2] = std::lround (p[53]);
+  s[1] = std::llround (p[54]);
+  p[55] = std::remquo (p[55], p[113], q + 4);
+  p[56] = std::fma (p[56], p[114], p[115]);
+  p[57] = std::lerp (p[57], p[116], p[117]);
+  p[58] = std::assoc_laguerre (q[5], q[6], p[58]);
+  p[59] = std::assoc_legendre (q[7], q[8], p[59]);
+  p[60] = std::beta (p[60], p[118]);
+  p[61] = std::comp_ellint_1 (p[61]);
+  p[62] = std::comp_ellint_2 (p[62]);
+  p[63] = std::comp_ellint_3 (p[63], p[119]);
+  p[64] = std::cyl_bessel_i (p[64], p[120]);
+  p[65] = std::cyl_bessel_j (p[65], p[121]);
+  p[66] = std::cyl_bessel_k (p[66], p[122]);
+  p[67] = std::cyl_neumann (p[67], p[123]);
+  p[68] = std::ellint_1 (p[68], p[124]);
+  p[69] = std::ellint_2 (p[69], p[125]);
+  p[70] = std::ellint_3 (p[70], p[126], p[127]);
+  p[71] = std::expint (p[71]);
+  p[72] = std::hermite (q[9], p[72]);
+  p[73] = std::laguerre (q[10], p[73]);
+  p[74] = std::legendre (q[11], p[72]);
+  p[75] = std::riemann_zeta (p[75]);
+  p[76] = std::sph_bessel (q[12], p[76]);
+  p[77] = std::sph_legendre (q[13], q[14], p[77]);
+  p[78] = std::sph_neumann (q[15], q[16], p[78]);
+}
+
+int
+main ()
+{
+  int q[17] = {};
+  long int r[16] = {};
+  long long int s[16] = {};
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  {
+    std::float16_t p[128] = {};
+    test_functions (p, q, r, s);
+  }
+#endif
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  {
+    std::float32_t p[128] = {};
+    test_functions (p, q, r, s);
+  }
+#endif
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+  {
+    std::float64_t p[128] = {};
+    test_functions (p, q, r, s);
+  }
+#endif
+#if defined(__STDCPP_FLOAT128_T__) \
+    && (defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY128) \
+	|| defined(_GLIBCXX_HAVE_FLOAT128_MATH))
+  {
+    std::float128_t p[128] = {};
+    test_functions (p, q, r, s);
+  }
+#endif
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+  {
+    std::bfloat16_t p[128] = {};
+    test_functions (p, q, r, s);
+  }
+#endif
+}
--- libstdc++-v3/testsuite/26_numerics/numbers/4.cc.jj	2022-10-14 22:32:55.415346407 +0200
+++ libstdc++-v3/testsuite/26_numerics/numbers/4.cc	2022-10-14 22:32:55.415346407 +0200
@@ -0,0 +1,122 @@ 
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This 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 General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2b" }
+// { dg-do compile { target c++23 } }
+
+#include <numbers>
+#include <stdfloat>
+
+#if defined(__STDCPP_FLOAT16_T__)
+void
+test01()
+{
+  const std::float16_t* d1  = &std::numbers::e_v<std::float16_t>;
+  const std::float16_t* d2  = &std::numbers::log2e_v<std::float16_t>;
+  const std::float16_t* d3  = &std::numbers::log10e_v<std::float16_t>;
+  const std::float16_t* d4  = &std::numbers::pi_v<std::float16_t>;
+  const std::float16_t* d5  = &std::numbers::inv_pi_v<std::float16_t>;
+  const std::float16_t* d6  = &std::numbers::inv_sqrtpi_v<std::float16_t>;
+  const std::float16_t* d7  = &std::numbers::ln2_v<std::float16_t>;
+  const std::float16_t* d8  = &std::numbers::ln10_v<std::float16_t>;
+  const std::float16_t* d9  = &std::numbers::sqrt2_v<std::float16_t>;
+  const std::float16_t* d10 = &std::numbers::sqrt3_v<std::float16_t>;
+  const std::float16_t* d11 = &std::numbers::inv_sqrt3_v<std::float16_t>;
+  const std::float16_t* d12 = &std::numbers::egamma_v<std::float16_t>;
+  const std::float16_t* d13 = &std::numbers::phi_v<std::float16_t>;
+}
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__)
+void
+test02()
+{
+  const std::float32_t* d1  = &std::numbers::e_v<std::float32_t>;
+  const std::float32_t* d2  = &std::numbers::log2e_v<std::float32_t>;
+  const std::float32_t* d3  = &std::numbers::log10e_v<std::float32_t>;
+  const std::float32_t* d4  = &std::numbers::pi_v<std::float32_t>;
+  const std::float32_t* d5  = &std::numbers::inv_pi_v<std::float32_t>;
+  const std::float32_t* d6  = &std::numbers::inv_sqrtpi_v<std::float32_t>;
+  const std::float32_t* d7  = &std::numbers::ln2_v<std::float32_t>;
+  const std::float32_t* d8  = &std::numbers::ln10_v<std::float32_t>;
+  const std::float32_t* d9  = &std::numbers::sqrt2_v<std::float32_t>;
+  const std::float32_t* d10 = &std::numbers::sqrt3_v<std::float32_t>;
+  const std::float32_t* d11 = &std::numbers::inv_sqrt3_v<std::float32_t>;
+  const std::float32_t* d12 = &std::numbers::egamma_v<std::float32_t>;
+  const std::float32_t* d13 = &std::numbers::phi_v<std::float32_t>;
+}
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__)
+void
+test03()
+{
+  const std::float64_t* d1  = &std::numbers::e_v<std::float64_t>;
+  const std::float64_t* d2  = &std::numbers::log2e_v<std::float64_t>;
+  const std::float64_t* d3  = &std::numbers::log10e_v<std::float64_t>;
+  const std::float64_t* d4  = &std::numbers::pi_v<std::float64_t>;
+  const std::float64_t* d5  = &std::numbers::inv_pi_v<std::float64_t>;
+  const std::float64_t* d6  = &std::numbers::inv_sqrtpi_v<std::float64_t>;
+  const std::float64_t* d7  = &std::numbers::ln2_v<std::float64_t>;
+  const std::float64_t* d8  = &std::numbers::ln10_v<std::float64_t>;
+  const std::float64_t* d9  = &std::numbers::sqrt2_v<std::float64_t>;
+  const std::float64_t* d10 = &std::numbers::sqrt3_v<std::float64_t>;
+  const std::float64_t* d11 = &std::numbers::inv_sqrt3_v<std::float64_t>;
+  const std::float64_t* d12 = &std::numbers::egamma_v<std::float64_t>;
+  const std::float64_t* d13 = &std::numbers::phi_v<std::float64_t>;
+}
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__)
+void
+test04()
+{
+  const std::float128_t* d1  = &std::numbers::e_v<std::float128_t>;
+  const std::float128_t* d2  = &std::numbers::log2e_v<std::float128_t>;
+  const std::float128_t* d3  = &std::numbers::log10e_v<std::float128_t>;
+  const std::float128_t* d4  = &std::numbers::pi_v<std::float128_t>;
+  const std::float128_t* d5  = &std::numbers::inv_pi_v<std::float128_t>;
+  const std::float128_t* d6  = &std::numbers::inv_sqrtpi_v<std::float128_t>;
+  const std::float128_t* d7  = &std::numbers::ln2_v<std::float128_t>;
+  const std::float128_t* d8  = &std::numbers::ln10_v<std::float128_t>;
+  const std::float128_t* d9  = &std::numbers::sqrt2_v<std::float128_t>;
+  const std::float128_t* d10 = &std::numbers::sqrt3_v<std::float128_t>;
+  const std::float128_t* d11 = &std::numbers::inv_sqrt3_v<std::float128_t>;
+  const std::float128_t* d12 = &std::numbers::egamma_v<std::float128_t>;
+  const std::float128_t* d13 = &std::numbers::phi_v<std::float128_t>;
+}
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__)
+void
+test05()
+{
+  const std::bfloat16_t* d1  = &std::numbers::e_v<std::bfloat16_t>;
+  const std::bfloat16_t* d2  = &std::numbers::log2e_v<std::bfloat16_t>;
+  const std::bfloat16_t* d3  = &std::numbers::log10e_v<std::bfloat16_t>;
+  const std::bfloat16_t* d4  = &std::numbers::pi_v<std::bfloat16_t>;
+  const std::bfloat16_t* d5  = &std::numbers::inv_pi_v<std::bfloat16_t>;
+  const std::bfloat16_t* d6  = &std::numbers::inv_sqrtpi_v<std::bfloat16_t>;
+  const std::bfloat16_t* d7  = &std::numbers::ln2_v<std::bfloat16_t>;
+  const std::bfloat16_t* d8  = &std::numbers::ln10_v<std::bfloat16_t>;
+  const std::bfloat16_t* d9  = &std::numbers::sqrt2_v<std::bfloat16_t>;
+  const std::bfloat16_t* d10 = &std::numbers::sqrt3_v<std::bfloat16_t>;
+  const std::bfloat16_t* d11 = &std::numbers::inv_sqrt3_v<std::bfloat16_t>;
+  const std::bfloat16_t* d12 = &std::numbers::egamma_v<std::bfloat16_t>;
+  const std::bfloat16_t* d13 = &std::numbers::phi_v<std::bfloat16_t>;
+}
+#endif
--- libstdc++-v3/testsuite/29_atomics/atomic_float/requirements_cxx23.cc.jj	2022-10-14 22:32:55.416346393 +0200
+++ libstdc++-v3/testsuite/29_atomics/atomic_float/requirements_cxx23.cc	2022-10-14 22:32:55.416346393 +0200
@@ -0,0 +1,112 @@ 
+// Copyright (C) 2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This 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 General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2b" }
+// { dg-do compile { target c++23 } }
+
+#include <atomic>
+#include <stdfloat>
+
+#if defined(__STDCPP_FLOAT16_T__)
+void
+test01()
+{
+  using A = std::atomic<std::float16_t>;
+  static_assert( std::is_standard_layout_v<A> );
+  static_assert( !std::is_trivially_default_constructible_v<A> );
+  static_assert( std::is_trivially_destructible_v<A> );
+  static_assert( std::is_same_v<A::value_type, std::float16_t> );
+  static_assert( std::is_same_v<A::difference_type, A::value_type> );
+  static_assert( !std::is_copy_constructible_v<A> );
+  static_assert( !std::is_move_constructible_v<A> );
+  static_assert( !std::is_copy_assignable_v<A> );
+  static_assert( !std::is_move_assignable_v<A> );
+  static_assert( !std::is_assignable_v<volatile A&, const A&> );
+}
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__)
+void
+test02()
+{
+  using A = std::atomic<std::float32_t>;
+  static_assert( std::is_standard_layout_v<A> );
+  static_assert( !std::is_trivially_default_constructible_v<A> );
+  static_assert( std::is_trivially_destructible_v<A> );
+  static_assert( std::is_same_v<A::value_type, std::float32_t> );
+  static_assert( std::is_same_v<A::difference_type, A::value_type> );
+  static_assert( !std::is_copy_constructible_v<A> );
+  static_assert( !std::is_move_constructible_v<A> );
+  static_assert( !std::is_copy_assignable_v<A> );
+  static_assert( !std::is_move_assignable_v<A> );
+  static_assert( !std::is_assignable_v<volatile A&, const A&> );
+}
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__)
+void
+test03()
+{
+  using A = std::atomic<std::float64_t>;
+  static_assert( std::is_standard_layout_v<A> );
+  static_assert( !std::is_trivially_default_constructible_v<A> );
+  static_assert( std::is_trivially_destructible_v<A> );
+  static_assert( std::is_same_v<A::value_type, std::float64_t> );
+  static_assert( std::is_same_v<A::difference_type, A::value_type> );
+  static_assert( !std::is_copy_constructible_v<A> );
+  static_assert( !std::is_move_constructible_v<A> );
+  static_assert( !std::is_copy_assignable_v<A> );
+  static_assert( !std::is_move_assignable_v<A> );
+  static_assert( !std::is_assignable_v<volatile A&, const A&> );
+}
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__)
+void
+test04()
+{
+  using A = std::atomic<std::float128_t>;
+  static_assert( std::is_standard_layout_v<A> );
+  static_assert( !std::is_trivially_default_constructible_v<A> );
+  static_assert( std::is_trivially_destructible_v<A> );
+  static_assert( std::is_same_v<A::value_type, std::float128_t> );
+  static_assert( std::is_same_v<A::difference_type, A::value_type> );
+  static_assert( !std::is_copy_constructible_v<A> );
+  static_assert( !std::is_move_constructible_v<A> );
+  static_assert( !std::is_copy_assignable_v<A> );
+  static_assert( !std::is_move_assignable_v<A> );
+  static_assert( !std::is_assignable_v<volatile A&, const A&> );
+}
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__)
+void
+test05()
+{
+  using A = std::atomic<std::bfloat16_t>;
+  static_assert( std::is_standard_layout_v<A> );
+  static_assert( !std::is_trivially_default_constructible_v<A> );
+  static_assert( std::is_trivially_destructible_v<A> );
+  static_assert( std::is_same_v<A::value_type, std::bfloat16_t> );
+  static_assert( std::is_same_v<A::difference_type, A::value_type> );
+  static_assert( !std::is_copy_constructible_v<A> );
+  static_assert( !std::is_move_constructible_v<A> );
+  static_assert( !std::is_copy_assignable_v<A> );
+  static_assert( !std::is_move_assignable_v<A> );
+  static_assert( !std::is_assignable_v<volatile A&, const A&> );
+}
+#endif