[llvm] f08b2fe - [Support][APint] Introduce and use isPowerOf2SlowCase instead countPopulationSlowCase for slow path (#189257)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 30 06:43:29 PDT 2026
Author: Max Graey
Date: 2026-03-30T15:43:18+02:00
New Revision: f08b2fefe84d0098c9f1cbb6d1688142884663de
URL: https://github.com/llvm/llvm-project/commit/f08b2fefe84d0098c9f1cbb6d1688142884663de
DIFF: https://github.com/llvm/llvm-project/commit/f08b2fefe84d0098c9f1cbb6d1688142884663de.diff
LOG: [Support][APint] Introduce and use isPowerOf2SlowCase instead countPopulationSlowCase for slow path (#189257)
In most cases `APint::isPowerOf2` returns false, but
`countPopulationSlowCase` always has `O(N)` complexity specifically for
the most common case, so I added `isPowerOf2SlowCase` method with an
early loop exit which should help a lot for most typical scenario.
Added:
Modified:
llvm/include/llvm/ADT/APInt.h
llvm/lib/Support/APInt.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
index b6a659dde1b15..683eea4fb19a3 100644
--- a/llvm/include/llvm/ADT/APInt.h
+++ b/llvm/include/llvm/ADT/APInt.h
@@ -443,7 +443,7 @@ class [[nodiscard]] APInt {
assert(BitWidth && "zero width values not allowed");
return isPowerOf2_64(U.VAL);
}
- return countPopulationSlowCase() == 1;
+ return isPowerOf2SlowCase();
}
/// Check if this APInt's negated value is a power of two greater than zero.
@@ -2085,6 +2085,9 @@ class [[nodiscard]] APInt {
/// out-of-line slow case for countPopulation
LLVM_ABI unsigned countPopulationSlowCase() const LLVM_READONLY;
+ /// out-of-line slow case for isPowerOf2
+ LLVM_ABI bool isPowerOf2SlowCase() const LLVM_READONLY;
+
/// out-of-line slow case for intersects.
LLVM_ABI bool intersectsSlowCase(const APInt &RHS) const LLVM_READONLY;
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 0a9cda5299fc8..3348b3d4396ce 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -660,7 +660,7 @@ APInt APInt::getSplat(unsigned NewLen, const APInt &V) {
unsigned APInt::countLeadingZerosSlowCase() const {
unsigned Count = 0;
- for (int i = getNumWords()-1; i >= 0; --i) {
+ for (int i = getNumWords() - 1; i >= 0; --i) {
uint64_t V = U.pVal[i];
if (V == 0)
Count += APINT_BITS_PER_WORD;
@@ -727,6 +727,16 @@ unsigned APInt::countPopulationSlowCase() const {
return Count;
}
+bool APInt::isPowerOf2SlowCase() const {
+ unsigned Count = 0;
+ for (unsigned i = 0; i < getNumWords(); ++i) {
+ Count += llvm::popcount(U.pVal[i]);
+ if (Count > 1)
+ return false;
+ }
+ return Count == 1;
+}
+
bool APInt::intersectsSlowCase(const APInt &RHS) const {
for (unsigned i = 0, e = getNumWords(); i != e; ++i)
if ((U.pVal[i] & RHS.U.pVal[i]) != 0)
More information about the llvm-commits
mailing list