[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