Skip to content

Commit 69e7635

Browse files
[Support] Add KnownBits::computeForSubBorrow
Implements computeForSubBorrow as alias for computeforAddCarry. Borrow is expected to be 1-bit wide. Adds exhaustive unit test.
1 parent 112e49b commit 69e7635

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

llvm/include/llvm/Support/KnownBits.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,10 @@ struct KnownBits {
332332
static KnownBits computeForAddSub(bool Add, bool NSW, const KnownBits &LHS,
333333
KnownBits RHS);
334334

335+
/// Compute known bits results from subtracting RHS from LHS with 1-bit Borrow.
336+
static KnownBits computeForSubBorrow(const KnownBits &LHS, KnownBits RHS,
337+
const KnownBits &Borrow);
338+
335339
/// Compute knownbits resulting from llvm.sadd.sat(LHS, RHS)
336340
static KnownBits sadd_sat(const KnownBits &LHS, const KnownBits &RHS);
337341

llvm/lib/Support/KnownBits.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,18 @@ KnownBits KnownBits::computeForAddSub(bool Add, bool NSW,
8585
return KnownOut;
8686
}
8787

88+
KnownBits KnownBits::computeForSubBorrow(const KnownBits &LHS, KnownBits RHS,
89+
const KnownBits &Borrow) {
90+
assert(Borrow.getBitWidth() == 1 && "Borrow must be 1-bit");
91+
92+
// LHS - RHS = LHS + ~RHS + 1
93+
// Carry 1 - Borrow in ::computeForAddCarry
94+
std::swap(RHS.Zero, RHS.One);
95+
return ::computeForAddCarry(LHS, RHS,
96+
/*CarryZero*/ Borrow.One.getBoolValue(),
97+
/*CarryOne*/ Borrow.Zero.getBoolValue());
98+
}
99+
88100
KnownBits KnownBits::sextInReg(unsigned SrcBitWidth) const {
89101
unsigned BitWidth = getBitWidth();
90102
assert(0 < SrcBitWidth && SrcBitWidth <= BitWidth &&

llvm/unittests/Support/KnownBitsTest.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,37 @@ TEST(KnownBitsTest, AddSubExhaustive) {
213213
TestAddSubExhaustive(false);
214214
}
215215

216+
TEST(KnownBitsTest, SubBorrowExhaustive) {
217+
unsigned Bits = 4;
218+
ForeachKnownBits(Bits, [&](const KnownBits &Known1) {
219+
ForeachKnownBits(Bits, [&](const KnownBits &Known2) {
220+
ForeachKnownBits(1, [&](const KnownBits &KnownBorrow) {
221+
// Explicitly compute known bits of the addition by trying all
222+
// possibilities.
223+
KnownBits Known(Bits);
224+
Known.Zero.setAllBits();
225+
Known.One.setAllBits();
226+
ForeachNumInKnownBits(Known1, [&](const APInt &N1) {
227+
ForeachNumInKnownBits(Known2, [&](const APInt &N2) {
228+
ForeachNumInKnownBits(KnownBorrow, [&](const APInt &Borrow) {
229+
APInt Sub = N1 - N2;
230+
if (Borrow.getBoolValue())
231+
--Sub;
232+
233+
Known.One &= Sub;
234+
Known.Zero &= ~Sub;
235+
});
236+
});
237+
});
238+
239+
KnownBits KnownComputed =
240+
KnownBits::computeForSubBorrow(Known1, Known2, KnownBorrow);
241+
EXPECT_EQ(Known, KnownComputed);
242+
});
243+
});
244+
});
245+
}
246+
216247
TEST(KnownBitsTest, BinaryExhaustive) {
217248
testBinaryOpExhaustive(
218249
[](const KnownBits &Known1, const KnownBits &Known2) {

0 commit comments

Comments
 (0)