[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