diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h index eb441bb31c9bc..3692b199c9ec1 100644 --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -704,10 +704,12 @@ struct zip_common : public zip_traits { using value_type = typename Base::value_type; std::tuple iterators; + mutable std::optional value; protected: - template value_type deref(std::index_sequence) const { - return value_type(*std::get(iterators)...); + template const value_type &deref(std::index_sequence) const { + value.emplace(*std::get(iterators)...); + return *value; } template void tup_inc(std::index_sequence) { @@ -728,7 +730,7 @@ struct zip_common : public zip_traits { public: zip_common(Iters &&... ts) : iterators(std::forward(ts)...) {} - value_type operator*() const { return deref(IndexSequence{}); } + const value_type &operator*() const { return deref(IndexSequence{}); } ZipType &operator++() { tup_inc(IndexSequence{}); diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 336126cc1fbc2..61aeb03634645 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -9991,7 +9991,7 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis { if (!E->ReorderIndices.empty() && CommonVF == E->ReorderIndices.size() && CommonVF == CommonMask.size() && any_of(enumerate(CommonMask), - [](const auto &&P) { + [](const auto &P) { return P.value() != PoisonMaskElem && static_cast(P.value()) != P.index(); }) && diff --git a/llvm/unittests/ADT/IteratorTest.cpp b/llvm/unittests/ADT/IteratorTest.cpp index a0d3c9b564d85..6c9aba8fcad2b 100644 --- a/llvm/unittests/ADT/IteratorTest.cpp +++ b/llvm/unittests/ADT/IteratorTest.cpp @@ -482,39 +482,26 @@ TEST(ZipIteratorTest, ZipEqualConstCorrectness) { EXPECT_THAT(first, ElementsAre(0, 0, 0)); EXPECT_THAT(second, ElementsAre(true, true, true)); - std::vector nemesis = {true, false, true}; - const std::vector c_nemesis = nemesis; - - for (auto &&[a, b, c, d] : zip_equal(first, c_first, nemesis, c_nemesis)) { + for (auto &&[a, b] : zip_equal(first, c_first)) { a = 2; - c = true; static_assert(!IsConstRef); static_assert(IsConstRef); - static_assert(!IsBoolConstRef); - static_assert(IsBoolConstRef); } EXPECT_THAT(first, ElementsAre(2, 2, 2)); - EXPECT_THAT(nemesis, ElementsAre(true, true, true)); unsigned iters = 0; - for (const auto &[a, b, c, d] : - zip_equal(first, c_first, nemesis, c_nemesis)) { + for (const auto &[a, b] : zip_equal(first, c_first)) { static_assert(!IsConstRef); static_assert(IsConstRef); - static_assert(!IsBoolConstRef); - static_assert(IsBoolConstRef); ++iters; } EXPECT_EQ(iters, 3u); iters = 0; - for (const auto &[a, b, c, d] : - MakeConst(zip_equal(first, c_first, nemesis, c_nemesis))) { + for (const auto &[a, b] : MakeConst(zip_equal(first, c_first))) { static_assert(!IsConstRef); static_assert(IsConstRef); - static_assert(!IsBoolConstRef); - static_assert(IsBoolConstRef); ++iters; } EXPECT_EQ(iters, 3u); @@ -643,6 +630,23 @@ TEST(ZipIteratorTest, Mutability) { } } +TEST(ZipIteratorTest, Lifetime) { + SmallVector v1 = {1, 2, 3, 4}; + SmallVector v2 = {5, 6, 7, 8}; + + auto zipper = zip(v1, v2); + + auto zip_iter = zipper.begin(); + EXPECT_NE(zip_iter, zipper.end()); + + auto *elem = &*zip_iter; + EXPECT_EQ(std::get<0>(*elem), 1u); + EXPECT_EQ(std::get<1>(*elem), 5u); + + std::get<0>(*elem) = 42; + EXPECT_EQ(v1[0], 42u); +} + TEST(ZipIteratorTest, ZipFirstMutability) { using namespace std; vector pi{3, 1, 4, 1, 5, 9};