[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