https://gcc.gnu.org/g:e2692b9ea7bde28de2a31a3580ce9dcc25e42fa4

commit r15-4777-ge2692b9ea7bde28de2a31a3580ce9dcc25e42fa4
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Thu Oct 24 11:40:42 2024 +0100

    libstdc++: Define config macros for additional IEEE formats
    
    Some targets use IEEE binary64 for both double and long double, which
    means we could use memmove to optimize a std::copy from a range of
    double to a range of long double. We currently have no config macro to
    detect when long double is binary64, so add that to <bits/c++config.h>.
    
    This also adds config macros for the case where double and long double
    both use the same binary32 format as float, which is true for the avr
    target. No specializations of __memcpyable for that case are added by
    this patch, but they could be added later.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/c++config (_GLIBCXX_DOUBLE_IS_IEEE_BINARY32):
            Define.
            (_GLIBCXX_LDOUBLE_IS_IEEE_BINARY64): Define.
            (_GLIBCXX_LDOUBLE_IS_IEEE_BINARY32): Define.
            * include/bits/cpp_type_traits.h (__memcpyable): Define
            specializations when double and long double are compatible.
    
    Reviewed-by: Patrick Palka <ppa...@redhat.com>

Diff:
---
 libstdc++-v3/include/bits/c++config         | 21 ++++++++++++++++++---
 libstdc++-v3/include/bits/cpp_type_traits.h |  7 +++++++
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/include/bits/c++config 
b/libstdc++-v3/include/bits/c++config
index b87a3527f24b..1076803a8655 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -836,25 +836,40 @@ namespace std
 # endif
 #endif
 
-// Define if float has the IEEE binary32 format.
 #if __FLT_MANT_DIG__ == 24 \
   && __FLT_MIN_EXP__ == -125 \
   && __FLT_MAX_EXP__ == 128
+// Define if float has the IEEE binary32 format.
 # define _GLIBCXX_FLOAT_IS_IEEE_BINARY32 1
 #endif
 
-// Define if double has the IEEE binary64 format.
 #if __DBL_MANT_DIG__ == 53 \
   && __DBL_MIN_EXP__ == -1021 \
   && __DBL_MAX_EXP__ == 1024
+// Define if double has the IEEE binary64 format.
 # define _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 1
+#elif __FLT_MANT_DIG__ == 24 \
+  && __FLT_MIN_EXP__ == -125 \
+  && __FLT_MAX_EXP__ == 128
+// Define if double has the IEEE binary32 format.
+# define _GLIBCXX_DOUBLE_IS_IEEE_BINARY32 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 if long double has the IEEE binary128 format.
 # define _GLIBCXX_LDOUBLE_IS_IEEE_BINARY128 1
+#elif __LDBL_MANT_DIG__ == 53 \
+  && __LDBL_MIN_EXP__ == -1021 \
+  && __LDBL_MAX_EXP__ == 1024
+// Define if long double has the IEEE binary64 format.
+# define _GLIBCXX_LDOUBLE_IS_IEEE_BINARY64 1
+#elif __LDBL_MANT_DIG__ == 24 \
+  && __LDBL_MIN_EXP__ == -125 \
+  && __LDBL_MAX_EXP__ == 128
+// Define if long double has the IEEE binary32 format.
+# define _GLIBCXX_LDOUBLE_IS_IEEE_BINARY32 1
 #endif
 
 #if defined __cplusplus && defined __BFLT16_DIG__
diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h 
b/libstdc++-v3/include/bits/cpp_type_traits.h
index e412f8d07703..e5a5efece42d 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -556,6 +556,13 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
     struct __memcpyable_integer<unsigned __int128> { enum { __width = 128 }; };
 #endif
 
+#if _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 && _GLIBCXX_LDOUBLE_IS_IEEE_BINARY64
+  template<>
+    struct __memcpyable<double*, long double*> { enum { __value = true }; };
+  template<>
+    struct __memcpyable<long double*, double*> { enum { __value = true }; };
+#endif
+
 #if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
   template<>
     struct __memcpyable<_Float32*, float*> { enum { __value = true }; };

Reply via email to