[llvm] [Support][APint] Add fast case for 128 bit-width in APInt::reverseBits (PR #189291)

Max Graey via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 30 07:18:00 PDT 2026


https://github.com/MaxGraey updated https://github.com/llvm/llvm-project/pull/189291

>From d0e25e4c17bec88cb254be38afa0f25640e21f10 Mon Sep 17 00:00:00 2001
From: MaxGraey <maxgraey at gmail.com>
Date: Mon, 30 Mar 2026 00:56:23 +0300
Subject: [PATCH 1/2] add case for 128 bit-width in APInt::reverseBits

---
 llvm/lib/Support/APInt.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 0a9cda5299fc8..ef36f9b782469 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -767,6 +767,12 @@ APInt APInt::byteSwap() const {
 
 APInt APInt::reverseBits() const {
   switch (BitWidth) {
+  case 128: {
+    APInt Result(BitWidth, 0);
+    Result.U.pVal[0] = llvm::reverseBits<uint64_t>(U.pVal[1]);
+    Result.U.pVal[1] = llvm::reverseBits<uint64_t>(U.pVal[0]);
+    return Result;
+  }
   case 64:
     return APInt(BitWidth, llvm::reverseBits<uint64_t>(U.VAL));
   case 32:

>From a8e33c614ce8366030c6c25c87a55bd06c4eb0ee Mon Sep 17 00:00:00 2001
From: MaxGraey <maxgraey at gmail.com>
Date: Mon, 30 Mar 2026 17:17:37 +0300
Subject: [PATCH 2/2] optimize fallback path in reverseBits

---
 llvm/lib/Support/APInt.cpp | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index ef36f9b782469..5a84741b2ef89 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -767,12 +767,6 @@ APInt APInt::byteSwap() const {
 
 APInt APInt::reverseBits() const {
   switch (BitWidth) {
-  case 128: {
-    APInt Result(BitWidth, 0);
-    Result.U.pVal[0] = llvm::reverseBits<uint64_t>(U.pVal[1]);
-    Result.U.pVal[1] = llvm::reverseBits<uint64_t>(U.pVal[0]);
-    return Result;
-  }
   case 64:
     return APInt(BitWidth, llvm::reverseBits<uint64_t>(U.VAL));
   case 32:
@@ -787,18 +781,24 @@ APInt APInt::reverseBits() const {
     break;
   }
 
-  APInt Val(*this);
-  APInt Reversed(BitWidth, 0);
-  unsigned S = BitWidth;
-
-  for (; Val != 0; Val.lshrInPlace(1)) {
-    Reversed <<= 1;
-    Reversed |= Val[0];
-    --S;
+  APInt Result(BitWidth, 0);
+  unsigned NumWords = getNumWords();
+  unsigned ExcessBits = NumWords * 64 - BitWidth;
+  if (LLVM_UNLIKELY(ExcessBits == 0)) {
+    // Fast path. No cross-word shift needed.
+    for (unsigned I = 0; I < NumWords; ++I)
+      Result.U.pVal[I] = llvm::reverseBits<uint64_t>(U.pVal[NumWords - 1 - I]);
+    return Result;
   }
-
-  Reversed <<= S;
-  return Reversed;
+  // Holds reversed bits of the previous (more significant) word.
+  uint64_t PrevRev = llvm::reverseBits<uint64_t>(U.pVal[NumWords - 1]);
+  for (unsigned I = 0; I < NumWords - 1; ++I) {
+    uint64_t CurrRev = llvm::reverseBits<uint64_t>(U.pVal[NumWords - 2 - I]);
+    Result.U.pVal[I] = (CurrRev >> ExcessBits) | (PrevRev << (64 - ExcessBits));
+    PrevRev = CurrRev;
+  }
+  Result.U.pVal[NumWords - 1] = PrevRev >> ExcessBits;
+  return Result;
 }
 
 APInt llvm::APIntOps::GreatestCommonDivisor(APInt A, APInt B) {



More information about the llvm-commits mailing list