[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