[llvm] 5d68f75 - [Analysis] Improve readability of `KnownBits::pext` and `KnownBits::pdep` (#205176)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 27 04:42:57 PDT 2026
Author: Jan Schultke
Date: 2026-06-27T11:42:52Z
New Revision: 5d68f75b53458604b11efb66192840f1cecd8ffa
URL: https://github.com/llvm/llvm-project/commit/5d68f75b53458604b11efb66192840f1cecd8ffa
DIFF: https://github.com/llvm/llvm-project/commit/5d68f75b53458604b11efb66192840f1cecd8ffa.diff
LOG: [Analysis] Improve readability of `KnownBits::pext` and `KnownBits::pdep` (#205176)
- Change the parameter names to `Val` and `Mask` to emphasize their semantics.
- Use `clearBits` instead of bitwise AND for increased expressiveness.
- Rewrite explanatory comments.
Added:
Modified:
llvm/include/llvm/Support/KnownBits.h
llvm/lib/Support/KnownBits.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h
index dc80a3f10b087..f88e5bdd1a92d 100644
--- a/llvm/include/llvm/Support/KnownBits.h
+++ b/llvm/include/llvm/Support/KnownBits.h
@@ -479,11 +479,11 @@ struct KnownBits {
/// Compute known bits for clmul(LHS, RHS).
LLVM_ABI static KnownBits clmul(const KnownBits &LHS, const KnownBits &RHS);
- /// Compute known bits for pext(LHS, RHS).
- LLVM_ABI static KnownBits pext(const KnownBits &LHS, const KnownBits &RHS);
+ /// Compute known bits for pext(Val, Mask).
+ LLVM_ABI static KnownBits pext(const KnownBits &Val, const KnownBits &Mask);
- /// Compute known bits for pdep(LHS, RHS).
- LLVM_ABI static KnownBits pdep(const KnownBits &LHS, const KnownBits &RHS);
+ /// Compute known bits for pdep(Val, Mask).
+ LLVM_ABI static KnownBits pdep(const KnownBits &Val, const KnownBits &Mask);
/// Determine if these known bits always give the same ICMP_EQ result.
LLVM_ABI static std::optional<bool> eq(const KnownBits &LHS,
diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp
index a2f71061fe0ad..d9c588780510c 100644
--- a/llvm/lib/Support/KnownBits.cpp
+++ b/llvm/lib/Support/KnownBits.cpp
@@ -645,66 +645,69 @@ KnownBits KnownBits::clmul(const KnownBits &LHS, const KnownBits &RHS) {
return Res;
}
-KnownBits KnownBits::pext(const KnownBits &LHS, const KnownBits &RHS) {
- // For each source position I where mask[I] could be set, the output index j
- // lies in [M0, M1] where these track the range of possible set-bit counts
- // seen so far in mask.
- //
- // The output bit j
- // - can be 0 if any candidate LHS[I] could be zero or popcount(mask) could
- // be <= j, and
- // - can be 1 only if some candidate LHS[I] could be one and popcount(mask)
- // is known > j.
- unsigned BitWidth = LHS.getBitWidth();
+KnownBits KnownBits::pext(const KnownBits &Val, const KnownBits &Mask) {
+ unsigned BitWidth = Val.getBitWidth();
KnownBits Res(BitWidth);
+ // We start by asserting that bits cannot be 0 and cannot be 1, then clear
+ // Res bits where we know a bit could have some value.
Res.setAllConflict();
+ // For each source position I where Mask[I] could be 1, the output position J
+ // lies in [M0, M1], where M0 and M1 track the range of possible 1-bit counts
+ // seen so far in Mask. Note that M0=M1 as long as bits in Mask are known;
+ // otherwise, the range of possible output positions widens.
unsigned M0 = 0, M1 = 0;
for (unsigned I = 0; I < BitWidth; ++I) {
- if (!RHS.Zero[I]) {
- APInt Range = APInt::getBitsSet(BitWidth, M0, M1 + 1);
- if (!LHS.Zero[I])
- Res.Zero &= ~Range; // some position in Range could be 1
- if (!LHS.One[I])
- Res.One &= ~Range; // some position in Range could be 0
+ if (!Mask.Zero[I]) {
+ // Mask[I] could be 1, so we decide what value the Res bits could have.
+ if (!Val.Zero[I])
+ // Val[I] could be 1 => Res[J] for J in [M0, M1] could be 1
+ Res.Zero.clearBits(M0, M1 + 1);
+ if (!Val.One[I])
+ // Val[I] could be 0 => Res[J] for J in [M0, M1] could be 0
+ Res.One.clearBits(M0, M1 + 1);
}
- if (RHS.One[I])
+ if (Mask.One[I])
++M0, ++M1;
- else if (!RHS.Zero[I])
+ else if (!Mask.Zero[I])
++M1;
}
- // Output positions j >= M0 may have no source (popcount(mask) <= j), in
- // which case they default to zero.
- Res.One &= APInt::getLowBitsSet(BitWidth, M0);
+ // Output bits at J >= M0 may have no source (popcount(Mask) may be <= J), so
+ // they may be 0.
+ Res.One.clearBits(M0, BitWidth);
return Res;
}
-KnownBits KnownBits::pdep(const KnownBits &LHS, const KnownBits &RHS) {
- // For each output position I where mask[I] could be set, the source index j
- // lies in [M0, M1] where these track possible counts of set mask bits < I.
- //
- // The output bit
- // - can be 0 if mask[I] or any candidate LHS[j] could be zero, and
- // - can be 1 only if both mask[I] and some candidate LHS[j] could be one.
- unsigned BitWidth = LHS.getBitWidth();
+KnownBits KnownBits::pdep(const KnownBits &Val, const KnownBits &Mask) {
+ unsigned BitWidth = Val.getBitWidth();
KnownBits Res(BitWidth);
+ // We start by asserting that bits cannot be 0 and cannot be 1, then clear
+ // Res bits where we know a bit could have some value.
Res.setAllConflict();
+ // For each output position I where Mask[I] could be 1, the source position J
+ // lies in [M0, M1], where M0 and M1 track the range of possible 1-bit counts
+ // seen so far in Mask. Note that M0=M1 as long as bits in Mask are known;
+ // otherwise, the range of possible source positions widens.
unsigned M0 = 0, M1 = 0;
for (unsigned I = 0; I < BitWidth; ++I) {
- if (!RHS.One[I])
- Res.One.clearBit(I); // mask[I] could be 0 -> output[I] could be 0
- if (!RHS.Zero[I]) {
+ if (!Mask.One[I])
+ // Mask[I] could be 0 => Res[I] could be 0
+ Res.One.clearBit(I);
+ if (!Mask.Zero[I]) {
+ // Mask[I] could be 1, so we check what value the Val bits could have.
APInt Range = APInt::getBitsSet(BitWidth, M0, M1 + 1);
- if (!Range.isSubsetOf(LHS.One))
- Res.One.clearBit(I); // some candidate could be 0
- if (!Range.isSubsetOf(LHS.Zero))
- Res.Zero.clearBit(I); // some candidate could be 1
+ if (!Range.isSubsetOf(Val.One))
+ // Any Val[J] for J in [M0, M1] could be 0 => Res[I] could be 0
+ Res.One.clearBit(I);
+ if (!Range.isSubsetOf(Val.Zero))
+ // Any Val[J] for J in [M0, M1] could be 1 => Res[I] could be 1
+ Res.Zero.clearBit(I);
}
- if (RHS.One[I])
+ if (Mask.One[I])
++M0, ++M1;
- else if (!RHS.Zero[I])
+ else if (!Mask.Zero[I])
++M1;
}
return Res;
More information about the llvm-commits
mailing list