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

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 10 16:55:46 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-adt

Author: Ryan Buchner (bababuck)

<details>
<summary>Changes</summary>

For `constexpr` iterables we can check sorted status at compile time rather than runtime.

`std::is_sorted` is not `constexpr` until Cpp20, so had to write a custom `is_sorted_constexpr` function.

Unit tests for `is_sorted_constexpr` were generated by AI.

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


3 Files Affected:

- (modified) llvm/include/llvm/ADT/STLExtras.h (+16) 
- (modified) llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp (+4-3) 
- (modified) llvm/unittests/ADT/STLExtrasTest.cpp (+29) 


``````````diff
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

``````````

</details>


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


More information about the llvm-commits mailing list