]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Add missing constexpr to simd_neon
authorMatthias Kretz <m.kretz@gsi.de>
Tue, 23 May 2023 21:48:49 +0000 (23:48 +0200)
committerMatthias Kretz <m.kretz@gsi.de>
Wed, 24 May 2023 11:06:35 +0000 (13:06 +0200)
Signed-off-by: Matthias Kretz <m.kretz@gsi.de>
libstdc++-v3/ChangeLog:

PR libstdc++/109261
* include/experimental/bits/simd_neon.h (_S_reduce): Add
constexpr and make NEON implementation conditional on
not __builtin_is_constant_evaluated.

libstdc++-v3/include/experimental/bits/simd_neon.h

index 637b121b1307e58742eb10e7943cce2a63337fa9..8f732d7587b013e79a075e235b7cc89307571132 100644 (file)
@@ -84,50 +84,46 @@ template <typename _Abi, typename>
     // }}}
     // _S_reduce {{{
     template <typename _Tp, typename _BinaryOperation>
-      _GLIBCXX_SIMD_INTRINSIC static _Tp
+      _GLIBCXX_SIMD_INTRINSIC static constexpr _Tp
       _S_reduce(simd<_Tp, _Abi> __x, _BinaryOperation&& __binary_op)
       {
-       constexpr size_t _Np = __x.size();
-       if constexpr (sizeof(__x) == 16 && _Np >= 4
-                     && !_Abi::template _S_is_partial<_Tp>)
-         {
-           const auto __halves = split<simd<_Tp, simd_abi::_Neon<8>>>(__x);
-           const auto __y = __binary_op(__halves[0], __halves[1]);
-           return _SimdImplNeon<simd_abi::_Neon<8>>::_S_reduce(
-             __y, static_cast<_BinaryOperation&&>(__binary_op));
-         }
-       else if constexpr (_Np == 8)
-         {
-           __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>(
-                                    __vector_permute<1, 0, 3, 2, 5, 4, 7, 6>(
-                                      __x._M_data)));
-           __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>(
-                                    __vector_permute<3, 2, 1, 0, 7, 6, 5, 4>(
-                                      __x._M_data)));
-           __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>(
-                                    __vector_permute<7, 6, 5, 4, 3, 2, 1, 0>(
-                                      __x._M_data)));
-           return __x[0];
-         }
-       else if constexpr (_Np == 4)
-         {
-           __x
-             = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>(
-                                  __vector_permute<1, 0, 3, 2>(__x._M_data)));
-           __x
-             = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>(
-                                  __vector_permute<3, 2, 1, 0>(__x._M_data)));
-           return __x[0];
-         }
-       else if constexpr (_Np == 2)
+       if (not __builtin_is_constant_evaluated())
          {
-           __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>(
-                                    __vector_permute<1, 0>(__x._M_data)));
-           return __x[0];
+           constexpr size_t _Np = __x.size();
+           if constexpr (sizeof(__x) == 16 && _Np >= 4
+                           && !_Abi::template _S_is_partial<_Tp>)
+             {
+               const auto __halves = split<simd<_Tp, simd_abi::_Neon<8>>>(__x);
+               const auto __y = __binary_op(__halves[0], __halves[1]);
+               return _SimdImplNeon<simd_abi::_Neon<8>>::_S_reduce(
+                        __y, static_cast<_BinaryOperation&&>(__binary_op));
+             }
+           else if constexpr (_Np == 8)
+             {
+               __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>(
+                                        __vector_permute<1, 0, 3, 2, 5, 4, 7, 6>(__x._M_data)));
+               __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>(
+                                        __vector_permute<3, 2, 1, 0, 7, 6, 5, 4>(__x._M_data)));
+               __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>(
+                                        __vector_permute<7, 6, 5, 4, 3, 2, 1, 0>(__x._M_data)));
+               return __x[0];
+             }
+           else if constexpr (_Np == 4)
+             {
+               __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>(
+                                        __vector_permute<1, 0, 3, 2>(__x._M_data)));
+               __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>(
+                                        __vector_permute<3, 2, 1, 0>(__x._M_data)));
+               return __x[0];
+             }
+           else if constexpr (_Np == 2)
+             {
+               __x = __binary_op(__x, _Base::template _M_make_simd<_Tp, _Np>(
+                                        __vector_permute<1, 0>(__x._M_data)));
+               return __x[0];
+             }
          }
-       else
-         return _Base::_S_reduce(__x,
-                                 static_cast<_BinaryOperation&&>(__binary_op));
+       return _Base::_S_reduce(__x, static_cast<_BinaryOperation&&>(__binary_op));
       }
 
     // }}}