[llvm] 8254cc9 - [APInt] Add fast path for APInt::urem if RHS is power of 2 (#189245)

via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 30 07:26:09 PDT 2026


Author: Max Graey
Date: 2026-03-30T16:26:04+02:00
New Revision: 8254cc9e574f4b2092065dc15f39babc522166c2

URL: https://github.com/llvm/llvm-project/commit/8254cc9e574f4b2092065dc15f39babc522166c2
DIFF: https://github.com/llvm/llvm-project/commit/8254cc9e574f4b2092065dc15f39babc522166c2.diff

LOG: [APInt] Add fast path for APInt::urem if RHS is power of 2 (#189245)

Added: 
    

Modified: 
    llvm/lib/Support/APInt.cpp
    llvm/unittests/ADT/APIntTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 3348b3d4396ce..f546de5e5da22 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -1715,6 +1715,12 @@ APInt APInt::urem(const APInt &RHS) const {
   if (lhsWords == 1)
     // All high words are zero, just use native remainder
     return APInt(BitWidth, U.pVal[0] % RHS.U.pVal[0]);
+  if (RHS.isPowerOf2()) {
+    // X % 2^w ===> X & (2^w - 1)
+    APInt Result(*this);
+    Result.clearBits(RHS.logBase2(), BitWidth);
+    return Result;
+  }
 
   // We have to compute it the hard way. Invoke the Knuth divide algorithm.
   APInt Remainder(BitWidth, 0);
@@ -1747,6 +1753,9 @@ uint64_t APInt::urem(uint64_t RHS) const {
   if (lhsWords == 1)
     // All high words are zero, just use native remainder
     return U.pVal[0] % RHS;
+  if (llvm::isPowerOf2_64(RHS))
+    // X % 2^w ===> X & (2^w - 1)
+    return getZExtValue() & (RHS - 1);
 
   // We have to compute it the hard way. Invoke the Knuth divide algorithm.
   uint64_t Remainder;

diff  --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp
index 9bd283953f733..34efc4ff8ccf5 100644
--- a/llvm/unittests/ADT/APIntTest.cpp
+++ b/llvm/unittests/ADT/APIntTest.cpp
@@ -1069,7 +1069,7 @@ TEST(APIntTest, divrem_big3) {
 }
 
 TEST(APIntTest, divrem_big4) {
-  // Tests heap allocation in divide() enfoced by huge numbers
+  // Tests heap allocation in divide() enforced by huge numbers
   testDiv(APInt{4096, 5}.shl(2001),
           APInt{4096, 1}.shl(2000),
           APInt{4096, 4219*13});


        


More information about the llvm-commits mailing list