@@ -116,42 +116,62 @@ template <class _VecT, class _Iter>
116
116
}(make_index_sequence<__simd_vector_size_v<_VecT>>{});
117
117
}
118
118
119
- template <class _Tp , size_t _Np>
120
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __all_of (__simd_vector<_Tp , _Np> __vec) noexcept {
121
- return __builtin_reduce_and (__builtin_convertvector ( __vec, __simd_vector< bool , _Np>) );
119
+ template <size_t _Np>
120
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __all_of (__simd_vector<bool , _Np> __vec) noexcept {
121
+ return __builtin_reduce_and (__vec);
122
122
}
123
123
124
124
template <class _Tp , size_t _Np>
125
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t __find_first_set (__simd_vector<_Tp, _Np> __vec) noexcept {
126
- using __mask_vec = __simd_vector<bool , _Np>;
125
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI auto __as_mask (__simd_vector<_Tp, _Np> __vec) noexcept {
126
+ static_assert (!is_same<_Tp, bool >::value, " vector type should not be a bool!" );
127
+ return __builtin_convertvector (__vec, __simd_vector<bool , _Np>);
128
+ }
127
129
128
- // This has MSan disabled du to https://github.com/llvm/llvm-project/issues/85876
129
- auto __impl = [&]<class _MaskT >(_MaskT) _LIBCPP_NO_SANITIZE (" memory" ) noexcept {
130
- # if defined(_LIBCPP_BIG_ENDIAN)
131
- return std::min<size_t >(
132
- _Np, std::__countl_zero (__builtin_bit_cast (_MaskT, __builtin_convertvector (__vec, __mask_vec))));
133
- # else
134
- return std::min<size_t >(
135
- _Np, std::__countr_zero (__builtin_bit_cast (_MaskT, __builtin_convertvector (__vec, __mask_vec))));
136
- # endif
137
- };
138
-
139
- if constexpr (sizeof (__mask_vec) == sizeof (uint8_t )) {
140
- return __impl (uint8_t {});
141
- } else if constexpr (sizeof (__mask_vec) == sizeof (uint16_t )) {
142
- return __impl (uint16_t {});
143
- } else if constexpr (sizeof (__mask_vec) == sizeof (uint32_t )) {
144
- return __impl (uint32_t {});
145
- } else if constexpr (sizeof (__mask_vec) == sizeof (uint64_t )) {
146
- return __impl (uint64_t {});
130
+ // This uses __builtin_convertvector around the __builtin_shufflevector to work around #107981.
131
+ template <size_t _Np>
132
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI __simd_vector<bool , 8 >
133
+ __extend_vector (__simd_vector<bool , _Np> __vec) noexcept {
134
+ using _VecT = __simd_vector<bool , _Np>;
135
+ if constexpr (_Np == 4 ) {
136
+ return __builtin_convertvector (
137
+ __builtin_shufflevector (__vec, _VecT{}, 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ), __simd_vector<bool , 8 >);
138
+ } else if constexpr (_Np == 2 ) {
139
+ return std::__extend_vector (
140
+ __builtin_convertvector (__builtin_shufflevector (__vec, _VecT{}, 0 , 1 , 2 , 3 ), __simd_vector<bool , 4 >));
147
141
} else {
148
- static_assert (sizeof (__mask_vec) == 0 , " unexpected required size for mask integer type" );
142
+ static_assert (sizeof (_VecT) == 0 , " Unexpected vector size" );
143
+ }
144
+ }
145
+
146
+ template <size_t _Np>
147
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI auto __to_int_mask (__simd_vector<bool , _Np> __vec) {
148
+ if constexpr (_Np < 8 ) {
149
+ return std::__bit_cast<uint8_t >(std::__extend_vector (__vec));
150
+ } else if constexpr (_Np == 8 ) {
151
+ return std::__bit_cast<uint8_t >(__vec);
152
+ } else if constexpr (_Np == 16 ) {
153
+ return std::__bit_cast<uint16_t >(__vec);
154
+ } else if constexpr (_Np == 32 ) {
155
+ return std::__bit_cast<uint32_t >(__vec);
156
+ } else if constexpr (_Np == 64 ) {
157
+ return std::__bit_cast<uint64_t >(__vec);
158
+ } else {
159
+ static_assert (sizeof (__simd_vector<bool , _Np>) == 0 , " Unexpected vector size" );
149
160
return 0 ;
150
161
}
151
162
}
152
163
153
- template <class _Tp , size_t _Np>
154
- [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t __find_first_not_set (__simd_vector<_Tp, _Np> __vec) noexcept {
164
+ template <size_t _Np>
165
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t __find_first_set (__simd_vector<bool , _Np> __vec) noexcept {
166
+ # if defined(_LIBCPP_BIG_ENDIAN)
167
+ return std::min<size_t >(_Np, std::__countl_zero (std::__to_int_mask (__vec)));
168
+ # else
169
+ return std::min<size_t >(_Np, std::__countr_zero (std::__to_int_mask (__vec)));
170
+ # endif
171
+ }
172
+
173
+ template <size_t _Np>
174
+ [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI size_t __find_first_not_set (__simd_vector<bool , _Np> __vec) noexcept {
155
175
return std::__find_first_set (~__vec);
156
176
}
157
177
0 commit comments