[libcxx-commits] [libcxx] [libc++] Fix endianness for algorithm mismatch (PR #93082)
via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jun 3 11:37:37 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libcxx
Author: Zibi Sarbinowski (zibi2)
<details>
<summary>Changes</summary>
This PR will fix `std/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp` test for big endian platrofrms such as z/OS.
---
Full diff: https://github.com/llvm/llvm-project/pull/93082.diff
1 Files Affected:
- (modified) libcxx/include/__algorithm/mismatch.h (+41-6)
``````````diff
diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h
index 632bec02406a4..bdd3314ed1ec5 100644
--- a/libcxx/include/__algorithm/mismatch.h
+++ b/libcxx/include/__algorithm/mismatch.h
@@ -55,7 +55,32 @@ __mismatch(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Pred& __pred, _Pro
}
#if _LIBCPP_VECTORIZE_ALGORITHMS
-
+template <class _ValueType, size_t _Np>
+_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __simd_vector<long long, _Np>
+__reverse_vector(__simd_vector<long long, _Np> __cmp_res) {
+ return [&]<size_t... _Indices>(index_sequence<_Indices...>) {
+ return __builtin_shufflevector(__cmp_res, __cmp_res, (_Np - _Indices - 1)...);
+ }(make_index_sequence<_Np>{});
+}
+template <class _ValueType, size_t _Np>
+_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __simd_vector<long, _Np> __reverse_vector(__simd_vector<long, _Np> __cmp_res) {
+ return [&]<size_t... _Indices>(index_sequence<_Indices...>) {
+ return __builtin_shufflevector(__cmp_res, __cmp_res, (_Np - _Indices - 1)...);
+ }(make_index_sequence<_Np>{});
+}
+template <class _ValueType, size_t _Np>
+_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __simd_vector<int, _Np> __reverse_vector(__simd_vector<int, _Np> __cmp_res) {
+ return [&]<size_t... _Indices>(index_sequence<_Indices...>) {
+ return __builtin_shufflevector(__cmp_res, __cmp_res, (_Np - _Indices - 1)...);
+ }(make_index_sequence<_Np>{});
+}
+template <class _ValueType, size_t _Np>
+_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI __simd_vector<_ValueType, _Np>
+__reverse_vector(__simd_vector<_ValueType, _Np> __cmp_res) {
+ return [&]<size_t... _Indices>(index_sequence<_Indices...>) {
+ return __builtin_shufflevector(__cmp_res, __cmp_res, (_Np - _Indices - 1)...);
+ }(make_index_sequence<_Np>{});
+}
template <class _Iter>
_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter, _Iter>
__mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
@@ -77,7 +102,11 @@ __mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
}
for (size_t __i = 0; __i != __unroll_count; ++__i) {
- if (auto __cmp_res = __lhs[__i] == __rhs[__i]; !std::__all_of(__cmp_res)) {
+ auto __cmp_res = __lhs[__i] == __rhs[__i];
+# if defined(_LIBCPP_BIG_ENDIAN)
+ __cmp_res = std::__reverse_vector<__value_type>(__cmp_res);
+# endif
+ if (!std::__all_of(__cmp_res)) {
auto __offset = __i * __vec_size + std::__find_first_not_set(__cmp_res);
return {__first1 + __offset, __first2 + __offset};
}
@@ -89,8 +118,11 @@ __mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
// check the remaining 0-3 vectors
while (static_cast<size_t>(__last1 - __first1) >= __vec_size) {
- if (auto __cmp_res = std::__load_vector<__vec>(__first1) == std::__load_vector<__vec>(__first2);
- !std::__all_of(__cmp_res)) {
+ auto __cmp_res = std::__load_vector<__vec>(__first1) == std::__load_vector<__vec>(__first2);
+# if defined(_LIBCPP_BIG_ENDIAN)
+ __cmp_res = std::__reverse_vector<__value_type>(__cmp_res);
+# endif
+ if (!std::__all_of(__cmp_res)) {
auto __offset = std::__find_first_not_set(__cmp_res);
return {__first1 + __offset, __first2 + __offset};
}
@@ -106,8 +138,11 @@ __mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) {
if (static_cast<size_t>(__first1 - __orig_first1) >= __vec_size) {
__first1 = __last1 - __vec_size;
__first2 = __last2 - __vec_size;
- auto __offset =
- std::__find_first_not_set(std::__load_vector<__vec>(__first1) == std::__load_vector<__vec>(__first2));
+ auto __cmp_res = std::__load_vector<__vec>(__first1) == std::__load_vector<__vec>(__first2);
+# if defined(_LIBCPP_BIG_ENDIAN)
+ __cmp_res = std::__reverse_vector<__value_type>(__cmp_res);
+# endif
+ auto __offset = std::__find_first_not_set(__cmp_res);
return {__first1 + __offset, __first2 + __offset};
} // else loop over the elements individually
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/93082
More information about the libcxx-commits
mailing list