Skip to content

[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

Merged
merged 9 commits into from
Jun 11, 2024

Conversation

zibi2
Copy link
Contributor

@zibi2 zibi2 commented May 22, 2024

This PR will fix std/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp test for big endian platrofrms such as z/OS.

@zibi2 zibi2 requested a review from philnik777 May 22, 2024 18:07
@zibi2 zibi2 self-assigned this May 22, 2024
Copy link

github-actions bot commented May 22, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@zibi2 zibi2 changed the title Fix endianess for algorithm mismatch Fix endianness for algorithm mismatch May 22, 2024
@zibi2 zibi2 force-pushed the zs_mismatch_big_endian branch from 11df170 to 05395e0 Compare May 22, 2024 19:49
@zibi2 zibi2 changed the title Fix endianness for algorithm mismatch [libc++] Fix endianness for algorithm mismatch May 22, 2024
@zibi2 zibi2 force-pushed the zs_mismatch_big_endian branch 2 times, most recently from 6cb78f6 to b4ce872 Compare May 23, 2024 20:10
@zibi2
Copy link
Contributor Author

zibi2 commented May 27, 2024

ping @philnik777 any recommendations?

@zibi2 zibi2 marked this pull request as ready for review June 3, 2024 18:36
@zibi2 zibi2 requested a review from a team as a code owner June 3, 2024 18:37
@zibi2 zibi2 requested a review from philnik777 June 3, 2024 18:37
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Jun 3, 2024
@llvmbot
Copy link
Member

llvmbot commented Jun 3, 2024

@llvm/pr-subscribers-libcxx

Author: Zibi Sarbinowski (zibi2)

Changes

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 --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
   }

@zibi2 zibi2 force-pushed the zs_mismatch_big_endian branch from 826d205 to 5eba555 Compare June 10, 2024 13:36
Copy link
Contributor

@philnik777 philnik777 left a 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.

@zibi2 zibi2 merged commit ffc3a6b into llvm:main Jun 11, 2024
9 of 11 checks passed
Lukacma pushed a commit to Lukacma/llvm-project that referenced this pull request Jun 12, 2024
This PR is required to fix
`std/algorithms/alg.nonmodifying/mismatch/mismatch.pass.cpp` test for
big endian platrofrms such as z/OS.
@HerrCai0907 HerrCai0907 mentioned this pull request Jun 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants