[llvm] [SLP] Use static_assert() rather than assert() where possible (PR #180867)

Ryan Buchner via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 11 13:46:13 PST 2026


https://github.com/bababuck updated https://github.com/llvm/llvm-project/pull/180867

>From fa7428d187b07f7c0c64e3f9a3a578fbccd655e0 Mon Sep 17 00:00:00 2001
From: bababuck <rbuchner at qti.qualcomm.com>
Date: Tue, 3 Feb 2026 16:56:54 -0800
Subject: [PATCH 1/7] [SLP] Use static_assert() rather than assert() where
 possible

Tests for is_sorted_constexpr were generated by AI.
---
 llvm/include/llvm/ADT/STLExtras.h             | 16 ++++++++++
 .../Transforms/Vectorize/SLPVectorizer.cpp    |  7 +++--
 llvm/unittests/ADT/STLExtrasTest.cpp          | 29 +++++++++++++++++++
 3 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h
index 23da931a63de1..62e1ee94758a7 100644
--- a/llvm/include/llvm/ADT/STLExtras.h
+++ b/llvm/include/llvm/ADT/STLExtras.h
@@ -1975,6 +1975,22 @@ template <typename R> bool is_sorted(R &&Range) {
   return std::is_sorted(adl_begin(Range), adl_end(Range));
 }
 
+/// Check if elements in a range \p R are sorted with respect to a comparator \p
+/// C. constexpr allows use in static_assert
+/// TODO: Use std::is_sorted once upgraded to Cpp20
+template <typename It, typename Cmp = std::less<>>
+constexpr bool is_sorted_constexpr(It First, It Last, Cmp C = Cmp{}) {
+  if (First == Last)
+    return true;
+  It Prev = First;
+  for (It I = std::next(First); I != Last; ++I) {
+    if (C(*I, *Prev))
+      return false;
+    Prev = I;
+  }
+  return true;
+}
+
 /// Provide wrappers to std::includes which take ranges instead of having to
 /// pass begin/end explicitly.
 /// This function checks if the sorted range \p R2 is a subsequence of the
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 1f92cc15135b4..1560503fcbf22 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -954,6 +954,9 @@ class BinOpSameOpcodeHelper {
   constexpr static std::initializer_list<unsigned> SupportedOp = {
       Instruction::Add,  Instruction::Sub, Instruction::Mul, Instruction::Shl,
       Instruction::AShr, Instruction::And, Instruction::Or,  Instruction::Xor};
+  static_assert(llvm::is_sorted_constexpr(SupportedOp.begin(),
+                                          SupportedOp.end()) &&
+                "SupportedOp is not sorted.");
   enum : MaskType {
     ShlBIT = 0b1,
     AShrBIT = 0b10,
@@ -1157,9 +1160,7 @@ class BinOpSameOpcodeHelper {
 public:
   BinOpSameOpcodeHelper(const Instruction *MainOp,
                         const Instruction *AltOp = nullptr)
-      : MainOp(MainOp), AltOp(AltOp) {
-    assert(is_sorted(SupportedOp) && "SupportedOp is not sorted.");
-  }
+      : MainOp(MainOp), AltOp(AltOp) {}
   bool add(const Instruction *I) {
     assert(isa<BinaryOperator>(I) &&
            "BinOpSameOpcodeHelper only accepts BinaryOperator.");
diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp
index fe71945e4a794..1312f31057491 100644
--- a/llvm/unittests/ADT/STLExtrasTest.cpp
+++ b/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -1937,4 +1937,33 @@ TEST(STLExtrasTest, AdjacentFind) {
   EXPECT_EQ(*std::next(It13), 3);
 }
 
+// Compile-time tests for llvm::is_sorted_constexpr
+static constexpr std::array<int, 0> CEmpty{};
+static_assert(is_sorted_constexpr(CEmpty.begin(), CEmpty.end()),
+              "Empty range should be sorted");
+
+static constexpr std::array<int, 1> CSingle{{42}};
+static_assert(is_sorted_constexpr(CSingle.begin(), CSingle.end()),
+              "Single element range should be sorted");
+static_assert(is_sorted_constexpr(CSingle.begin(), CSingle.end(),
+                                  std::greater<>()),
+              "Single element range should be sorted with std::greater");
+
+static constexpr std::array<int, 5> CSorted{{1, 2, 2, 3, 5}};
+static_assert(is_sorted_constexpr(CSorted.begin(), CSorted.end()),
+              "Non-descending order with duplicates should be sorted");
+static_assert(is_sorted_constexpr(CSorted.begin(), CSorted.end(),
+                                  std::less<>()),
+              "Explicit std::less non-descending order should be sorted");
+static_assert(!is_sorted_constexpr(CSorted.begin(), CSorted.end(),
+                                   std::greater<>()),
+              "Non-descending order should not be sorted by std::greater");
+
+static constexpr std::array<int, 5> CUnsorted{{1, 3, 2, 4, 5}};
+static_assert(!is_sorted_constexpr(CUnsorted.begin(), CUnsorted.end()),
+              "Unsorted range should not be sorted");
+
+static constexpr std::array<int, 5> CDesc{{9, 7, 7, 3, 0}};
+static_assert(is_sorted_constexpr(CDesc.begin(), CDesc.end(), std::greater<>()),
+              "Non-ascending order with std::greater should be sorted");
 } // namespace

>From 5d4dfa7b51fc413004d9270b9acc4be6aa527de7 Mon Sep 17 00:00:00 2001
From: bababuck <buchner.ryan at gmail.com>
Date: Wed, 11 Feb 2026 08:45:39 -0800
Subject: [PATCH 2/7] [SLP] Revert SLP, this is now an ADT only MR

---
 llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 1560503fcbf22..1f92cc15135b4 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -954,9 +954,6 @@ class BinOpSameOpcodeHelper {
   constexpr static std::initializer_list<unsigned> SupportedOp = {
       Instruction::Add,  Instruction::Sub, Instruction::Mul, Instruction::Shl,
       Instruction::AShr, Instruction::And, Instruction::Or,  Instruction::Xor};
-  static_assert(llvm::is_sorted_constexpr(SupportedOp.begin(),
-                                          SupportedOp.end()) &&
-                "SupportedOp is not sorted.");
   enum : MaskType {
     ShlBIT = 0b1,
     AShrBIT = 0b10,
@@ -1160,7 +1157,9 @@ class BinOpSameOpcodeHelper {
 public:
   BinOpSameOpcodeHelper(const Instruction *MainOp,
                         const Instruction *AltOp = nullptr)
-      : MainOp(MainOp), AltOp(AltOp) {}
+      : MainOp(MainOp), AltOp(AltOp) {
+    assert(is_sorted(SupportedOp) && "SupportedOp is not sorted.");
+  }
   bool add(const Instruction *I) {
     assert(isa<BinaryOperator>(I) &&
            "BinOpSameOpcodeHelper only accepts BinaryOperator.");

>From a34793e21aaba0986f7888d4ca9c38cab444b3eb Mon Sep 17 00:00:00 2001
From: bababuck <buchner.ryan at gmail.com>
Date: Wed, 11 Feb 2026 08:50:40 -0800
Subject: [PATCH 3/7] [ADT] Move is_sorted_constexpr() to STLForwardCompat.h

---
 llvm/include/llvm/ADT/STLExtras.h        | 16 ----------------
 llvm/include/llvm/ADT/STLForwardCompat.h | 17 +++++++++++++++++
 2 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h
index 62e1ee94758a7..23da931a63de1 100644
--- a/llvm/include/llvm/ADT/STLExtras.h
+++ b/llvm/include/llvm/ADT/STLExtras.h
@@ -1975,22 +1975,6 @@ template <typename R> bool is_sorted(R &&Range) {
   return std::is_sorted(adl_begin(Range), adl_end(Range));
 }
 
-/// Check if elements in a range \p R are sorted with respect to a comparator \p
-/// C. constexpr allows use in static_assert
-/// TODO: Use std::is_sorted once upgraded to Cpp20
-template <typename It, typename Cmp = std::less<>>
-constexpr bool is_sorted_constexpr(It First, It Last, Cmp C = Cmp{}) {
-  if (First == Last)
-    return true;
-  It Prev = First;
-  for (It I = std::next(First); I != Last; ++I) {
-    if (C(*I, *Prev))
-      return false;
-    Prev = I;
-  }
-  return true;
-}
-
 /// Provide wrappers to std::includes which take ranges instead of having to
 /// pass begin/end explicitly.
 /// This function checks if the sorted range \p R2 is a subsequence of the
diff --git a/llvm/include/llvm/ADT/STLForwardCompat.h b/llvm/include/llvm/ADT/STLForwardCompat.h
index d61c880747502..6a60f3beaf181 100644
--- a/llvm/include/llvm/ADT/STLForwardCompat.h
+++ b/llvm/include/llvm/ADT/STLForwardCompat.h
@@ -18,6 +18,7 @@
 #define LLVM_ADT_STLFORWARDCOMPAT_H
 
 #include "llvm/Support/Compiler.h"
+#include <functional>
 #include <optional>
 #include <tuple>
 #include <type_traits>
@@ -158,6 +159,22 @@ invoke(FnT &&Fn, ArgsT &&...Args) { // NOLINT(readability-identifier-naming)
                     std::forward_as_tuple(std::forward<ArgsT>(Args)...));
 }
 
+/// Check if elements in a range \p R are sorted with respect to a comparator \p
+/// C. constexpr allows use in static_assert
+/// TODO: Use std::is_sorted once upgraded to C++20 since that becomes constexpr
+template <typename It, typename Cmp = std::less<>>
+constexpr bool is_sorted_constexpr(It First, It Last, Cmp C = Cmp{}) {
+  if (First == Last)
+    return true;
+  It Prev = First;
+  for (It I = std::next(First); I != Last; ++I) {
+    if (C(*I, *Prev))
+      return false;
+    Prev = I;
+  }
+  return true;
+}
+
 //===----------------------------------------------------------------------===//
 //     Features from C++23
 //===----------------------------------------------------------------------===//

>From 82d1a53aec92ebda5041a59da16b54fa0b4c96ae Mon Sep 17 00:00:00 2001
From: bababuck <buchner.ryan at gmail.com>
Date: Wed, 11 Feb 2026 10:03:29 -0800
Subject: [PATCH 4/7] [ADT] Update is_sorted_constexpr() to operate on a Range

---
 llvm/include/llvm/ADT/STLForwardCompat.h | 10 ++++++----
 llvm/unittests/ADT/STLExtrasTest.cpp     | 20 ++++++++------------
 2 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/llvm/include/llvm/ADT/STLForwardCompat.h b/llvm/include/llvm/ADT/STLForwardCompat.h
index 6a60f3beaf181..9afffbcb8c848 100644
--- a/llvm/include/llvm/ADT/STLForwardCompat.h
+++ b/llvm/include/llvm/ADT/STLForwardCompat.h
@@ -162,12 +162,14 @@ invoke(FnT &&Fn, ArgsT &&...Args) { // NOLINT(readability-identifier-naming)
 /// Check if elements in a range \p R are sorted with respect to a comparator \p
 /// C. constexpr allows use in static_assert
 /// TODO: Use std::is_sorted once upgraded to C++20 since that becomes constexpr
-template <typename It, typename Cmp = std::less<>>
-constexpr bool is_sorted_constexpr(It First, It Last, Cmp C = Cmp{}) {
+template <typename R, typename Cmp = std::less<>>
+constexpr bool is_sorted_constexpr(R &&Range, Cmp C = Cmp{}) {
+  auto First = adl_begin(Range);
+  auto Last = adl_end(Range);
   if (First == Last)
     return true;
-  It Prev = First;
-  for (It I = std::next(First); I != Last; ++I) {
+  auto Prev = First;
+  for (auto I = std::next(First); I != Last; ++I) {
     if (C(*I, *Prev))
       return false;
     Prev = I;
diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp
index 1312f31057491..a52d13ca4f983 100644
--- a/llvm/unittests/ADT/STLExtrasTest.cpp
+++ b/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -1939,31 +1939,27 @@ TEST(STLExtrasTest, AdjacentFind) {
 
 // Compile-time tests for llvm::is_sorted_constexpr
 static constexpr std::array<int, 0> CEmpty{};
-static_assert(is_sorted_constexpr(CEmpty.begin(), CEmpty.end()),
-              "Empty range should be sorted");
+static_assert(is_sorted_constexpr(CEmpty), "Empty range should be sorted");
 
 static constexpr std::array<int, 1> CSingle{{42}};
-static_assert(is_sorted_constexpr(CSingle.begin(), CSingle.end()),
+static_assert(is_sorted_constexpr(CSingle),
               "Single element range should be sorted");
-static_assert(is_sorted_constexpr(CSingle.begin(), CSingle.end(),
-                                  std::greater<>()),
+static_assert(is_sorted_constexpr(CSingle, std::greater<>()),
               "Single element range should be sorted with std::greater");
 
 static constexpr std::array<int, 5> CSorted{{1, 2, 2, 3, 5}};
-static_assert(is_sorted_constexpr(CSorted.begin(), CSorted.end()),
+static_assert(is_sorted_constexpr(CSorted),
               "Non-descending order with duplicates should be sorted");
-static_assert(is_sorted_constexpr(CSorted.begin(), CSorted.end(),
-                                  std::less<>()),
+static_assert(is_sorted_constexpr(CSorted, std::less<>()),
               "Explicit std::less non-descending order should be sorted");
-static_assert(!is_sorted_constexpr(CSorted.begin(), CSorted.end(),
-                                   std::greater<>()),
+static_assert(!is_sorted_constexpr(CSorted, std::greater<>()),
               "Non-descending order should not be sorted by std::greater");
 
 static constexpr std::array<int, 5> CUnsorted{{1, 3, 2, 4, 5}};
-static_assert(!is_sorted_constexpr(CUnsorted.begin(), CUnsorted.end()),
+static_assert(!is_sorted_constexpr(CUnsorted),
               "Unsorted range should not be sorted");
 
 static constexpr std::array<int, 5> CDesc{{9, 7, 7, 3, 0}};
-static_assert(is_sorted_constexpr(CDesc.begin(), CDesc.end(), std::greater<>()),
+static_assert(is_sorted_constexpr(CDesc, std::greater<>()),
               "Non-ascending order with std::greater should be sorted");
 } // namespace

>From 6c70cf44d859511d1abd73a9cf10bea63ba3e0e6 Mon Sep 17 00:00:00 2001
From: bababuck <buchner.ryan at gmail.com>
Date: Wed, 11 Feb 2026 11:39:37 -0800
Subject: [PATCH 5/7] [ADT] Use typespace identifier for is_sorted_constexpr()
 in unittest

---
 llvm/unittests/ADT/STLExtrasTest.cpp | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp
index a52d13ca4f983..a76336febd2a0 100644
--- a/llvm/unittests/ADT/STLExtrasTest.cpp
+++ b/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -1939,27 +1939,28 @@ TEST(STLExtrasTest, AdjacentFind) {
 
 // Compile-time tests for llvm::is_sorted_constexpr
 static constexpr std::array<int, 0> CEmpty{};
-static_assert(is_sorted_constexpr(CEmpty), "Empty range should be sorted");
+static_assert(llvm::is_sorted_constexpr(CEmpty),
+              "Empty range should be sorted");
 
 static constexpr std::array<int, 1> CSingle{{42}};
-static_assert(is_sorted_constexpr(CSingle),
+static_assert(llvm::is_sorted_constexpr(CSingle),
               "Single element range should be sorted");
-static_assert(is_sorted_constexpr(CSingle, std::greater<>()),
+static_assert(llvm::is_sorted_constexpr(CSingle, std::greater<>()),
               "Single element range should be sorted with std::greater");
 
 static constexpr std::array<int, 5> CSorted{{1, 2, 2, 3, 5}};
-static_assert(is_sorted_constexpr(CSorted),
+static_assert(llvm::is_sorted_constexpr(CSorted),
               "Non-descending order with duplicates should be sorted");
-static_assert(is_sorted_constexpr(CSorted, std::less<>()),
+static_assert(llvm::is_sorted_constexpr(CSorted, std::less<>()),
               "Explicit std::less non-descending order should be sorted");
-static_assert(!is_sorted_constexpr(CSorted, std::greater<>()),
+static_assert(!llvm::is_sorted_constexpr(CSorted, std::greater<>()),
               "Non-descending order should not be sorted by std::greater");
 
 static constexpr std::array<int, 5> CUnsorted{{1, 3, 2, 4, 5}};
-static_assert(!is_sorted_constexpr(CUnsorted),
+static_assert(!llvm::is_sorted_constexpr(CUnsorted),
               "Unsorted range should not be sorted");
 
 static constexpr std::array<int, 5> CDesc{{9, 7, 7, 3, 0}};
-static_assert(is_sorted_constexpr(CDesc, std::greater<>()),
+static_assert(llvm::is_sorted_constexpr(CDesc, std::greater<>()),
               "Non-ascending order with std::greater should be sorted");
 } // namespace

>From f4b65cb1464dada93dd18aa9abd461cdb34eef59 Mon Sep 17 00:00:00 2001
From: bababuck <buchner.ryan at gmail.com>
Date: Wed, 11 Feb 2026 11:44:38 -0800
Subject: [PATCH 6/7] [ADT] Move tests to STLForwardCompatTest.cpp

---
 llvm/unittests/ADT/STLExtrasTest.cpp        | 26 --------------------
 llvm/unittests/ADT/STLForwardCompatTest.cpp | 27 +++++++++++++++++++++
 2 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp
index a76336febd2a0..fe71945e4a794 100644
--- a/llvm/unittests/ADT/STLExtrasTest.cpp
+++ b/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -1937,30 +1937,4 @@ TEST(STLExtrasTest, AdjacentFind) {
   EXPECT_EQ(*std::next(It13), 3);
 }
 
-// Compile-time tests for llvm::is_sorted_constexpr
-static constexpr std::array<int, 0> CEmpty{};
-static_assert(llvm::is_sorted_constexpr(CEmpty),
-              "Empty range should be sorted");
-
-static constexpr std::array<int, 1> CSingle{{42}};
-static_assert(llvm::is_sorted_constexpr(CSingle),
-              "Single element range should be sorted");
-static_assert(llvm::is_sorted_constexpr(CSingle, std::greater<>()),
-              "Single element range should be sorted with std::greater");
-
-static constexpr std::array<int, 5> CSorted{{1, 2, 2, 3, 5}};
-static_assert(llvm::is_sorted_constexpr(CSorted),
-              "Non-descending order with duplicates should be sorted");
-static_assert(llvm::is_sorted_constexpr(CSorted, std::less<>()),
-              "Explicit std::less non-descending order should be sorted");
-static_assert(!llvm::is_sorted_constexpr(CSorted, std::greater<>()),
-              "Non-descending order should not be sorted by std::greater");
-
-static constexpr std::array<int, 5> CUnsorted{{1, 3, 2, 4, 5}};
-static_assert(!llvm::is_sorted_constexpr(CUnsorted),
-              "Unsorted range should not be sorted");
-
-static constexpr std::array<int, 5> CDesc{{9, 7, 7, 3, 0}};
-static_assert(llvm::is_sorted_constexpr(CDesc, std::greater<>()),
-              "Non-ascending order with std::greater should be sorted");
 } // namespace
diff --git a/llvm/unittests/ADT/STLForwardCompatTest.cpp b/llvm/unittests/ADT/STLForwardCompatTest.cpp
index 8831062109cb3..cbd1899083d1b 100644
--- a/llvm/unittests/ADT/STLForwardCompatTest.cpp
+++ b/llvm/unittests/ADT/STLForwardCompatTest.cpp
@@ -605,5 +605,32 @@ TEST(STLForwardCompatTest, BindFrontBindBack) {
   EXPECT_TRUE(any_of(V, Spec1));
 }
 
+// Compile-time tests for llvm::is_sorted_constexpr
+static constexpr std::array<int, 0> CEmpty{};
+static_assert(llvm::is_sorted_constexpr(CEmpty),
+              "Empty range should be sorted");
+
+static constexpr std::array<int, 1> CSingle{{42}};
+static_assert(llvm::is_sorted_constexpr(CSingle),
+              "Single element range should be sorted");
+static_assert(llvm::is_sorted_constexpr(CSingle, std::greater<>()),
+              "Single element range should be sorted with std::greater");
+
+static constexpr std::array<int, 5> CSorted{{1, 2, 2, 3, 5}};
+static_assert(llvm::is_sorted_constexpr(CSorted),
+              "Non-descending order with duplicates should be sorted");
+static_assert(llvm::is_sorted_constexpr(CSorted, std::less<>()),
+              "Explicit std::less non-descending order should be sorted");
+static_assert(!llvm::is_sorted_constexpr(CSorted, std::greater<>()),
+              "Non-descending order should not be sorted by std::greater");
+
+static constexpr std::array<int, 5> CUnsorted{{1, 3, 2, 4, 5}};
+static_assert(!llvm::is_sorted_constexpr(CUnsorted),
+              "Unsorted range should not be sorted");
+
+static constexpr std::array<int, 5> CDesc{{9, 7, 7, 3, 0}};
+static_assert(llvm::is_sorted_constexpr(CDesc, std::greater<>()),
+              "Non-ascending order with std::greater should be sorted");
+
 } // namespace
 } // namespace llvm

>From 6c8039ce7b1f8831a8132e60b24c4e4fed4e9821 Mon Sep 17 00:00:00 2001
From: bababuck <buchner.ryan at gmail.com>
Date: Wed, 11 Feb 2026 13:18:48 -0800
Subject: [PATCH 7/7] [ADT] Use std::begin/std::end rather than adt_begin and
 adt_end

This addition is for forward compatibility, not for ADT compatibility.
---
 llvm/include/llvm/ADT/STLForwardCompat.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/ADT/STLForwardCompat.h b/llvm/include/llvm/ADT/STLForwardCompat.h
index 9afffbcb8c848..d08e7dbfa4aaf 100644
--- a/llvm/include/llvm/ADT/STLForwardCompat.h
+++ b/llvm/include/llvm/ADT/STLForwardCompat.h
@@ -164,8 +164,8 @@ invoke(FnT &&Fn, ArgsT &&...Args) { // NOLINT(readability-identifier-naming)
 /// TODO: Use std::is_sorted once upgraded to C++20 since that becomes constexpr
 template <typename R, typename Cmp = std::less<>>
 constexpr bool is_sorted_constexpr(R &&Range, Cmp C = Cmp{}) {
-  auto First = adl_begin(Range);
-  auto Last = adl_end(Range);
+  auto First = std::begin(Range);
+  auto Last = std::end(Range);
   if (First == Last)
     return true;
   auto Prev = First;



More information about the llvm-commits mailing list