[libcxx-commits] [libcxx] Fix __mismatch under _LIBCPP_VECTORIZE_ALGORITHMS guard (PR #91995)

via libcxx-commits libcxx-commits at lists.llvm.org
Mon May 13 09:53:31 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: None (zibi2)

<details>
<summary>Changes</summary>

Fix a regression within `std/ranges/range.adaptors/range.lazy.split/general.pass.cpp`
caused on z/OS after this [commit](https://github.com/llvm/llvm-project/commit/985c1a44f8d49e0af).

This test case is passing on other platforms such as AIX. This is because `__ALTIVEC__` macro is defined and  `__mismatch` under `_LIBCPP_VECTORIZE_ALGORITHMS` guard is disabled.  However, on z/OS  `_LIBCPP_VECTORIZE_ALGORITHMS`  is defined. This is isolated to overlapping separator cases.

Here is a subset of original test which fails on z/OS:

```
#include <ranges>
#include <cassert>
#include <vector>

template <class Char>
class BasicSmallString {
  std::vector<Char> buffer_{};

public:
  constexpr BasicSmallString(std::basic_string_view<Char> v)
    requires (std::same_as<Char, char> ||
              std::same_as<Char, wchar_t> ||
              std::same_as<Char, char8_t> ||
              std::same_as<Char, char16_t> ||
              std::same_as<Char, char32_t>)
    : buffer_(v.begin(), v.end())
  {}

  template <class I, class S>
  constexpr BasicSmallString(I b, const S& e) {
    for (; b != e; ++b) {
      buffer_.push_back(*b);
    }
  }

  template <std::ranges::range R>
  constexpr BasicSmallString(R&& from) : BasicSmallString(from.begin(), from.end()) {}

  friend constexpr bool operator==(const BasicSmallString& lhs, const BasicSmallString& rhs) {
    return lhs.buffer_ == rhs.buffer_;
  }
};

template <std::ranges::view View, std::ranges::range Expected>
constexpr bool is_equal(View& view, const Expected& expected) {
  using Char = std::ranges::range_value_t<std::ranges::range_value_t<View>>;
  using Str = BasicSmallString<Char>;

  auto actual_it = view.begin();
  auto expected_it = expected.begin();
  for (; actual_it != view.end() && expected_it != expected.end(); ++actual_it, ++expected_it) {
    if (Str(*actual_it) != Str(*expected_it))
      return false;
  }

  return actual_it == view.end() && expected_it == expected.end();
}

int main() {
  using namespace std::string_view_literals;
  auto overlapping_sep = "ab"sv;
  std::array expected = {"a"sv, "aa"sv, ""sv, "b"sv};
  std::ranges::lazy_split_view v("aabaaababb"sv, overlapping_sep);
  assert(is_equal(v, expected));
  return 0;
}
```

---
Full diff: https://github.com/llvm/llvm-project/pull/91995.diff


1 Files Affected:

- (modified) libcxx/include/__algorithm/mismatch.h (+1-1) 


``````````diff
diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h
index 4ada29eabc470..302381e0c8021 100644
--- a/libcxx/include/__algorithm/mismatch.h
+++ b/libcxx/include/__algorithm/mismatch.h
@@ -92,7 +92,7 @@ __mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred& __pred, _Proj1& __
     }
 
     // check the remaining 0-3 vectors
-    while (static_cast<size_t>(__last1 - __first1) >= __vec_size) {
+    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 __offset = std::__find_first_not_set(__cmp_res);

``````````

</details>


https://github.com/llvm/llvm-project/pull/91995


More information about the libcxx-commits mailing list