Skip to content

Commit 693b196

Browse files
committed
[libc++] Run vector instructions during constant evaluation when Clang supports it
1 parent 8323ff0 commit 693b196

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

libcxx/include/__algorithm/mismatch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ __mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
6565
constexpr size_t __vec_size = __native_vector_size<__value_type>;
6666
using __vec = __simd_vector<__value_type, __vec_size>;
6767

68-
if (!__libcpp_is_constant_evaluated()) {
68+
if (!__libcpp_is_constant_evaluated() || _LIBCPP_HAS_CONSTEXPR_VECTORS) {
6969
auto __orig_first1 = __first1;
7070
auto __last2 = __first2 + (__last1 - __first1);
7171
while (static_cast<size_t>(__last1 - __first1) >= __unroll_count * __vec_size) [[__unlikely__]] {

libcxx/include/__algorithm/simd_utils.h

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4553
template <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.
110118
template <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

117126
template <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

122131
template <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

151170
template <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

Comments
 (0)