@@ -40,6 +40,14 @@ _LIBCPP_PUSH_MACROS
4040
4141#if _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS
4242
43+ # if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 2200
44+ # define _LIBCPP_HAS_CONSTEXPR_VECTORS 1
45+ # define _LIBCPP_VECTOR_CONSTEXPR _LIBCPP_CONSTEXPR
46+ # else
47+ # define _LIBCPP_HAS_CONSTEXPR_VECTORS 0
48+ # define _LIBCPP_VECTOR_CONSTEXPR
49+ # endif
50+
4351_LIBCPP_BEGIN_NAMESPACE_STD
4452
4553template <class _Tp >
@@ -108,30 +116,40 @@ using __simd_vector_underlying_type_t _LIBCPP_NODEBUG = decltype(std::__simd_vec
108116
109117// This isn't inlined without always_inline when loading chars.
110118template <class _VecT , class _Iter >
111- [[__nodiscard__]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _VecT __load_vector (_Iter __iter) noexcept {
119+ [[__nodiscard__]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_VECTOR_CONSTEXPR _VecT
120+ __load_vector (_Iter __iter) noexcept {
112121 return [=]<size_t ... _Indices>(index_sequence<_Indices...>) _LIBCPP_ALWAYS_INLINE noexcept {
113122 return _VecT{__iter[_Indices]...};
114123 }(make_index_sequence<__simd_vector_size_v<_VecT>>{});
115124}
116125
117126template <class _Tp , size_t _Np>
118- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __all_of (__simd_vector<_Tp, _Np> __vec) noexcept {
127+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_VECTOR_CONSTEXPR bool __all_of (__simd_vector<_Tp, _Np> __vec) noexcept {
119128 return __builtin_reduce_and (__builtin_convertvector (__vec, __simd_vector<bool , _Np>));
120129}
121130
122131template <class _Tp , size_t _Np>
123- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t __find_first_set (__simd_vector<_Tp, _Np> __vec) noexcept {
132+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_VECTOR_CONSTEXPR size_t
133+ __find_first_set (__simd_vector<_Tp, _Np> __vec) noexcept {
124134 using __mask_vec = __simd_vector<bool , _Np>;
125135
136+ # if _LIBCPP_HAS_CONSTEXPR_VECTORS
137+ # if defined(_LIBCPP_BIG_ENDIAN)
138+ return __builtin_clzg (__builtin_convertvector (__vec, __mask_vec), static_cast <int >(_Np));
139+ # else
140+ return __builtin_ctzg (__builtin_convertvector (__vec, __mask_vec), static_cast <int >(_Np));
141+ # endif
142+ # else
143+
126144 // This has MSan disabled du to https://llvm.org/PR85876
127145 auto __impl = [&]<class _MaskT >(_MaskT) _LIBCPP_NO_SANITIZE (" memory" ) noexcept {
128- # if defined(_LIBCPP_BIG_ENDIAN)
146+ # if defined(_LIBCPP_BIG_ENDIAN)
129147 return std::min<size_t >(
130148 _Np, std::__countl_zero (__builtin_bit_cast (_MaskT, __builtin_convertvector (__vec, __mask_vec))));
131- # else
149+ # else
132150 return std::min<size_t >(
133151 _Np, std::__countr_zero (__builtin_bit_cast (_MaskT, __builtin_convertvector (__vec, __mask_vec))));
134- # endif
152+ # endif
135153 };
136154
137155 if constexpr (sizeof (__mask_vec) == sizeof (uint8_t )) {
@@ -146,10 +164,12 @@ template <class _Tp, size_t _Np>
146164 static_assert (sizeof (__mask_vec) == 0 , " unexpected required size for mask integer type" );
147165 return 0 ;
148166 }
167+ # endif
149168}
150169
151170template <class _Tp , size_t _Np>
152- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t __find_first_not_set (__simd_vector<_Tp, _Np> __vec) noexcept {
171+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_VECTOR_CONSTEXPR size_t
172+ __find_first_not_set (__simd_vector<_Tp, _Np> __vec) noexcept {
153173 return std::__find_first_set (~__vec);
154174}
155175
0 commit comments