[gcc(refs/users/aoliva/heads/testme)] libstdc++: simd: use preprocessor to test for 64-bit long double [PR124657]

Alexandre Oliva aoliva@gcc.gnu.org
Wed Apr 22 04:23:42 GMT 2026


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

commit edfd064941d8f6201310c10a0e33d9bb62cdeaa4
Author: Alexandre Oliva <oliva@adacore.com>
Date:   Thu Apr 16 01:06:00 2026 -0300

    libstdc++: simd: use preprocessor to test for 64-bit long double [PR124657]
    
    When long double is as wide as double on x86 or powerpc
    (-mlong-double-64), we remap it to double in __intrinsic_type.
    
    Use the preprocessor to compare __L?DBL_MANT_DIG instead of
    floating-type type sizes on x86 SSE and PowerPC AltiVec.
    
    
    for  libstdc++-v3/ChangeLog
    
            PR libstdc++/124657
            * include/experimental/bits/simd.h [_GLIBCXX_SIMD_HAVE_SSE]
            (__intrinsic_type::_S_is_ldouble): New.  Use all over.
            (__intrinsic_type::type): Use preprocessor tests.
            [__ALTIVEC__] (__intrinsic_type): Likewise.

Diff:
---
 libstdc++-v3/include/experimental/bits/simd.h | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/include/experimental/bits/simd.h b/libstdc++-v3/include/experimental/bits/simd.h
index 8c30c8af2688..177d3598b54b 100644
--- a/libstdc++-v3/include/experimental/bits/simd.h
+++ b/libstdc++-v3/include/experimental/bits/simd.h
@@ -2469,16 +2469,24 @@ template <>
 template <typename _Tp, size_t _Bytes>
   struct __intrinsic_type<_Tp, _Bytes, enable_if_t<__is_vectorizable_v<_Tp> && _Bytes <= 64>>
   {
+    static constexpr bool _S_is_ldouble = is_same_v<_Tp, long double>;
+
     // allow _Tp == long double with -mlong-double-64
-    static_assert(!(is_same_v<_Tp, long double>
-		    && sizeof(long double) > sizeof(double)),
+#if __LDBL_MANT_DIG != __DBL_MANT_DIG
+    static_assert(!_S_is_ldouble,
 		  "no __intrinsic_type support for long double on x86");
+#endif
 
     static constexpr size_t _S_VBytes = _Bytes <= 16 ? 16 : _Bytes <= 32 ? 32 : 64;
 
     using type [[__gnu__::__vector_size__(_S_VBytes)]]
       = conditional_t<is_integral_v<_Tp>, long long int,
-		      conditional_t<is_same_v<_Tp, long double>, double, _Tp> >;
+#if __LDBL_MANT_DIG != __DBL_MANT_DIG
+		      _Tp
+#else
+		      conditional_t<_S_is_ldouble, double, _Tp>
+#endif
+		      >;
   };
 #endif // _GLIBCXX_SIMD_HAVE_SSE
 
@@ -2582,12 +2590,17 @@ template <typename _Tp, size_t _Bytes>
     static constexpr bool _S_is_ldouble = is_same_v<_Tp, long double>;
 
     // allow _Tp == long double with -mlong-double-64
-    static_assert(!(_S_is_ldouble && sizeof(long double) > sizeof(double)),
+#if __LDBL_MANT_DIG != __DBL_MANT_DIG
+    static_assert(!_S_is_ldouble,
 		  "no __intrinsic_type support for 128-bit floating point on PowerPC");
+#endif
 
 #ifndef __VSX__
     static_assert(!(is_same_v<_Tp, double>
-		    || (_S_is_ldouble && sizeof(long double) == sizeof(double))),
+#if __LDBL_MANT_DIG == __DBL_MANT_DIG
+		    || _S_is_ldouble
+#endif
+		    ),
 		  "no __intrinsic_type support for 64-bit floating point on PowerPC w/o VSX");
 #endif
 
@@ -2595,9 +2608,11 @@ template <typename _Tp, size_t _Bytes>
     {
       if constexpr (is_floating_point_v<_Tp>)
 	{
+#if __LDBL_MANT_DIG == __DBL_MANT_DIG
 	  if constexpr (_S_is_ldouble)
 	    return double {};
 	  else
+#endif
 	    return _Tp {};
 	}
       else if constexpr (is_signed_v<_Tp>)


More information about the Libstdc++-cvs mailing list