Skip to content

Commit 6089f4f

Browse files
[CodeGen] Implement USUBC, USUBO_CARRY, and SSUBO_CARRY with KnownBits::computeForSubBorrow
1 parent 69e7635 commit 6089f4f

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3741,14 +3741,18 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
37413741
assert(Op.getResNo() == 0 &&
37423742
"We only compute knownbits for the difference here.");
37433743

3744-
// TODO: Compute influence of the carry operand.
3744+
// With USUBO_CARRY and SSUBO_CARRY a borrow bit may be added in.
3745+
KnownBits Borrow(1);
37453746
if (Opcode == ISD::USUBO_CARRY || Opcode == ISD::SSUBO_CARRY)
3746-
break;
3747+
// TODO: Compute known bits for the carry operand. Creates
3748+
// parity with UADDO_CARRY And SADDO_CARRY as of now.
3749+
Borrow.resetAll();
3750+
else
3751+
Borrow.setAllZero();
37473752

37483753
Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
37493754
Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
3750-
Known = KnownBits::computeForAddSub(/* Add */ false, /* NSW */ false,
3751-
Known, Known2);
3755+
Known = KnownBits::computeForSubBorrow(Known, Known2, Borrow);
37523756
break;
37533757
}
37543758
case ISD::UADDO:

llvm/unittests/CodeGen/AArch64SelectionDAGTest.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,30 @@ TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_SUB) {
273273
EXPECT_EQ(Known.One, APInt(8, 0x1));
274274
}
275275

276+
// Piggy-backing on the AArch64 tests to verify SelectionDAG::computeKnownBits.
277+
TEST_F(AArch64SelectionDAGTest, ComputeKnownBits_USUBO_CARRY) {
278+
SDLoc Loc;
279+
auto IntVT = EVT::getIntegerVT(Context, 8);
280+
auto N0 = DAG->getConstant(0x5a, Loc, IntVT);
281+
auto UnknownOp1 = DAG->getRegister(0, IntVT); // ????????
282+
auto Mask1_Zero = DAG->getConstant(0x8, Loc, IntVT); // 00001000
283+
auto Mask1_One = DAG->getConstant(0x20, Loc, IntVT); // 00100000
284+
// N1 = (???????? & 00001000) | 00100000 = 0010?000
285+
auto N1 = DAG->getNode(ISD::AND, Loc, IntVT, Mask1_Zero, UnknownOp1);
286+
N1 = DAG->getNode(ISD::OR, Loc, IntVT, Mask1_One, N1);
287+
auto UnknownOpC = DAG->getRegister(1, IntVT);
288+
auto Op = DAG->getNode(ISD::USUBO_CARRY, Loc, IntVT, N0, N1, UnknownOpC);
289+
// N0 = 01011010
290+
// N1 = 0010?000
291+
// C = ?
292+
// =>
293+
// Known.Zero = 11000100 (0xc4)
294+
// Known.One = 00110000 (0x30)
295+
KnownBits Known = DAG->computeKnownBits(Op);
296+
EXPECT_EQ(Known.Zero, APInt(8, 0xc4));
297+
EXPECT_EQ(Known.One, APInt(8, 0x30));
298+
}
299+
276300
TEST_F(AArch64SelectionDAGTest, isSplatValue_Fixed_BUILD_VECTOR) {
277301
TargetLowering TL(*TM);
278302

0 commit comments

Comments
 (0)