[llvm] a779fdf - [Support] Add KnownBits::isNonPositive() helper and exhaustive test coverage for sign predicates (#175284)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 11 06:02:54 PST 2026
Author: Aviral Garg
Date: 2026-01-11T14:02:49Z
New Revision: a779fdffe9bf6f2b15e558a56ae18061ffd48deb
URL: https://github.com/llvm/llvm-project/commit/a779fdffe9bf6f2b15e558a56ae18061ffd48deb
DIFF: https://github.com/llvm/llvm-project/commit/a779fdffe9bf6f2b15e558a56ae18061ffd48deb.diff
LOG: [Support] Add KnownBits::isNonPositive() helper and exhaustive test coverage for sign predicates (#175284)
This patch adds:
1. KnownBits::isNonPositive() - Returns true if this value is known to
be non-positive (i.e., the signed maximum value is <= 0). This is
implemented using getSignedMaxValue().isNonPositive().
2. SignPredicatesExhaustive test - An exhaustive test that validates the
correctness of isNegative(), isNonNegative(), isStrictlyPositive(),
isNonPositive(), and isNonZero() by iterating through all possible
KnownBits combinations for 1-bit and 4-bit widths and verifying that the
predicates return true if and only if all possible values represented by
the KnownBits satisfy the predicate.
Fixes #175203
Added:
Modified:
llvm/include/llvm/Support/KnownBits.h
llvm/unittests/Support/KnownBitsTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h
index bff944325880b..ea37b435e2848 100644
--- a/llvm/include/llvm/Support/KnownBits.h
+++ b/llvm/include/llvm/Support/KnownBits.h
@@ -115,6 +115,9 @@ struct KnownBits {
return Zero.isSignBitSet() && !One.isZero();
}
+ /// Returns true if this value is known to be non-positive.
+ bool isNonPositive() const { return getSignedMaxValue().isNonPositive(); }
+
/// Make this value negative.
void makeNegative() {
One.setSignBit();
diff --git a/llvm/unittests/Support/KnownBitsTest.cpp b/llvm/unittests/Support/KnownBitsTest.cpp
index ce0bf86e39dd7..abd0b3607c9fc 100644
--- a/llvm/unittests/Support/KnownBitsTest.cpp
+++ b/llvm/unittests/Support/KnownBitsTest.cpp
@@ -281,6 +281,47 @@ TEST(KnownBitsTest, SignBitUnknown) {
EXPECT_TRUE(Known.isSignUnknown());
}
+TEST(KnownBitsTest, SignPredicatesExhaustive) {
+ for (unsigned Bits : {1, 4}) {
+ ForeachKnownBits(Bits, [&](const KnownBits &Known) {
+ if (Known.hasConflict())
+ return;
+
+ bool AllNegative = true;
+ bool AllNonNegative = true;
+ bool AllStrictlyPositive = true;
+ bool AllNonPositive = true;
+ bool AllNonZero = true;
+
+ ForeachNumInKnownBits(Known, [&](const APInt &N) {
+ AllNegative &= N.isNegative();
+ AllNonNegative &= N.isNonNegative();
+ AllStrictlyPositive &= N.isStrictlyPositive();
+ AllNonPositive &= N.isNonPositive();
+ AllNonZero &= !N.isZero();
+ });
+
+ // isNegative() is optimal: returns true iff sign bit is known one.
+ EXPECT_EQ(AllNegative, Known.isNegative())
+ << "isNegative: Known = " << Known;
+ // isNonNegative() is optimal: returns true iff sign bit is known zero.
+ EXPECT_EQ(AllNonNegative, Known.isNonNegative())
+ << "isNonNegative: Known = " << Known;
+ // isStrictlyPositive() is optimal: returns true iff sign bit is known
+ // zero and at least one other bit is known one.
+ EXPECT_EQ(AllStrictlyPositive, Known.isStrictlyPositive())
+ << "isStrictlyPositive: Known = " << Known;
+ // isNonPositive() is optimal: returns true iff (sign bit is known one)
+ // or (known to be zero).
+ EXPECT_EQ(AllNonPositive, Known.isNonPositive())
+ << "isNonPositive: Known = " << Known;
+ // isNonZero() is optimal: returns true iff at least one bit is known one.
+ EXPECT_EQ(AllNonZero, Known.isNonZero())
+ << "isNonZero: Known = " << Known;
+ });
+ }
+}
+
TEST(KnownBitsTest, BinaryExhaustive) {
testBinaryOpExhaustive(
"and",
More information about the llvm-commits
mailing list