[llvm] [KnownBits] Optimize isConstant (NFC) (PR #191919)
Max Graey via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 14 02:15:27 PDT 2026
https://github.com/MaxGraey updated https://github.com/llvm/llvm-project/pull/191919
>From 9d46fe170eb503419bb2d02fdd50325c4f375f60 Mon Sep 17 00:00:00 2001
From: MaxGraey <maxgraey at gmail.com>
Date: Tue, 14 Apr 2026 04:18:19 +0300
Subject: [PATCH 1/5] simplify and optimize
---
llvm/include/llvm/Support/KnownBits.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h
index ecedccc9afd95..ee2477efa153f 100644
--- a/llvm/include/llvm/Support/KnownBits.h
+++ b/llvm/include/llvm/Support/KnownBits.h
@@ -52,7 +52,7 @@ struct KnownBits {
/// Returns true if we know the value of all bits.
bool isConstant() const {
- return Zero.popcount() + One.popcount() == getBitWidth();
+ return (Zero | One).isAllOnes();
}
/// Returns the value when all bits have a known value. This just returns One
>From 11194c63a83f743af5f4ba105c5c4dc8d425ccfc Mon Sep 17 00:00:00 2001
From: MaxGraey <maxgraey at gmail.com>
Date: Tue, 14 Apr 2026 04:23:51 +0300
Subject: [PATCH 2/5] format
---
llvm/include/llvm/Support/KnownBits.h | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h
index ee2477efa153f..96de46d821e8a 100644
--- a/llvm/include/llvm/Support/KnownBits.h
+++ b/llvm/include/llvm/Support/KnownBits.h
@@ -51,9 +51,7 @@ struct KnownBits {
bool hasConflict() const { return Zero.intersects(One); }
/// Returns true if we know the value of all bits.
- bool isConstant() const {
- return (Zero | One).isAllOnes();
- }
+ bool isConstant() const { return (Zero | One).isAllOnes(); }
/// Returns the value when all bits have a known value. This just returns One
/// with a protective assertion.
>From 7819d75d6eeb17e381398d5d86cb28410e7d07fe Mon Sep 17 00:00:00 2001
From: MaxGraey <maxgraey at gmail.com>
Date: Tue, 14 Apr 2026 11:40:01 +0300
Subject: [PATCH 3/5] use hybrid approach
---
llvm/include/llvm/Support/KnownBits.h | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h
index 96de46d821e8a..7f56149be6631 100644
--- a/llvm/include/llvm/Support/KnownBits.h
+++ b/llvm/include/llvm/Support/KnownBits.h
@@ -51,7 +51,13 @@ struct KnownBits {
bool hasConflict() const { return Zero.intersects(One); }
/// Returns true if we know the value of all bits.
- bool isConstant() const { return (Zero | One).isAllOnes(); }
+ bool isConstant() const {
+ if (Zero.isSingleWord()) {
+ return (Zero.getZExtValue() | One.getZExtValue()) ==
+ llvm::maskTrailingOnes<uint64_t>(getBitWidth());
+ }
+ return Zero.popcount() + One.popcount() == getBitWidth();
+ }
/// Returns the value when all bits have a known value. This just returns One
/// with a protective assertion.
>From d8b3b367c68b051d4fc4983b18ad306b700276c5 Mon Sep 17 00:00:00 2001
From: MaxGraey <maxgraey at gmail.com>
Date: Tue, 14 Apr 2026 11:43:51 +0300
Subject: [PATCH 4/5] format
---
llvm/include/llvm/Support/KnownBits.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h
index 7f56149be6631..8936a42246ea8 100644
--- a/llvm/include/llvm/Support/KnownBits.h
+++ b/llvm/include/llvm/Support/KnownBits.h
@@ -54,7 +54,7 @@ struct KnownBits {
bool isConstant() const {
if (Zero.isSingleWord()) {
return (Zero.getZExtValue() | One.getZExtValue()) ==
- llvm::maskTrailingOnes<uint64_t>(getBitWidth());
+ llvm::maskTrailingOnes<uint64_t>(getBitWidth());
}
return Zero.popcount() + One.popcount() == getBitWidth();
}
>From 807153f3304a4d704fc9b96db977566f0a13c1fc Mon Sep 17 00:00:00 2001
From: MaxGraey <maxgraey at gmail.com>
Date: Tue, 14 Apr 2026 12:15:10 +0300
Subject: [PATCH 5/5] add faster slow fallback
---
llvm/include/llvm/Support/KnownBits.h | 10 ++++++----
llvm/lib/Support/KnownBits.cpp | 14 ++++++++++++++
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h
index 8936a42246ea8..ffc71073bb554 100644
--- a/llvm/include/llvm/Support/KnownBits.h
+++ b/llvm/include/llvm/Support/KnownBits.h
@@ -52,11 +52,10 @@ struct KnownBits {
/// Returns true if we know the value of all bits.
bool isConstant() const {
- if (Zero.isSingleWord()) {
+ if (Zero.isSingleWord())
return (Zero.getZExtValue() | One.getZExtValue()) ==
- llvm::maskTrailingOnes<uint64_t>(getBitWidth());
- }
- return Zero.popcount() + One.popcount() == getBitWidth();
+ llvm::maskTrailingOnes<uint64_t>(getBitWidth());
+ return isConstantSlowCase();
}
/// Returns the value when all bits have a known value. This just returns One
@@ -580,6 +579,9 @@ struct KnownBits {
// Internal helper for getting the initial KnownBits for an `srem` or `urem`
// operation with the low-bits set.
static KnownBits remGetLowBits(const KnownBits &LHS, const KnownBits &RHS);
+
+ /// Multi-word case helper for isConstant().
+ bool isConstantSlowCase() const;
};
inline KnownBits operator&(KnownBits LHS, const KnownBits &RHS) {
diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp
index 07e7781d0839d..fc84f7b4100a7 100644
--- a/llvm/lib/Support/KnownBits.cpp
+++ b/llvm/lib/Support/KnownBits.cpp
@@ -19,6 +19,20 @@
using namespace llvm;
+bool KnownBits::isConstantSlowCase() const {
+ const unsigned LastWord = Zero.getNumWords() - 1;
+ const uint64_t *Zeros = Zero.getRawData();
+ const uint64_t *Ones = One.getRawData();
+
+ for (unsigned I = 0; I != LastWord; ++I)
+ if ((Zeros[I] | Ones[I]) != UINT64_MAX)
+ return false;
+
+ unsigned TailBits = getBitWidth() - LastWord * APInt::APINT_BITS_PER_WORD;
+ uint64_t TailMask = llvm::maskTrailingOnes<uint64_t>(TailBits);
+ return ((Zeros[LastWord] | Ones[LastWord]) & TailMask) == TailMask;
+}
+
KnownBits KnownBits::flipSignBit(const KnownBits &Val) {
unsigned SignBitPosition = Val.getBitWidth() - 1;
APInt Zero = Val.Zero;
More information about the llvm-commits
mailing list