[PATCH] libstdc++: simd: use preprocessor to test for 64-bit long double [PR124657]
Alexandre Oliva
oliva@adacore.com
Wed Apr 22 06:27:41 GMT 2026
On Apr 21, 2026, Jonathan Wakely <jwakely@redhat.com> wrote:
> #if __LDBL_MANT_DIG__ == __DBL_MANT_DIG__
I tried to apply the same technique to simd.h, on top of
https://gcc.gnu.org/pipermail/gcc-patches/2026-April/712616.html, but it
doesn't save any instantiations, neither on x86 nor on ppc. It seems to
make things generally uglier, but it might offer a little compile-time
benefit on both, so I left it as a separate patch... WDYT?
Also regstrapped on x86_64-linux-gnu and powerpc64le-linux-gnu. I also
tested pr109261_constexpr_simd.cc with -mlong-double-64 on both. Ok for
stage1?
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.
---
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 8c30c8af26881..177d3598b54b5 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>)
--
Alexandre Oliva, happy hacker https://blog.lx.oliva.nom.br/
Free Software Activist FSFLA co-founder GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity.
Excluding neuro-others for not behaving ""normal"" is *not* inclusive!
More information about the Libstdc++
mailing list