-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[libc++] Fix endianness for algorithm mismatch #93082
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
11df170
to
05395e0
Compare
6cb78f6
to
b4ce872
Compare
ping @philnik777 any recommendations? |
@llvm/pr-subscribers-libcxx Author: Zibi Sarbinowski (zibi2) ChangesThis PR will fix Full diff: https://github.com/llvm/llvm-project/pull/93082.diff 1 Files Affected:
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
}
|
826d205
to
5eba555
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with the nit addressed.
This PR is required to fix `std/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp` test for big endian platrofrms such as z/OS.
This PR will fix
std/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp
test for big endian platrofrms such as z/OS.