[Lldb-commits] [lldb] [Support] Add KnownBits::computeForSubBorrow (PR #67788)
https://github.com/christiankissig updated https://github.com/llvm/llvm-project/pull/67788 >From 5d86936c3a48c613460983c980271fcab8128b75 Mon Sep 17 00:00:00 2001 From: Christian Kissig Date: Tue, 26 Sep 2023 12:18:59 + Subject: [PATCH 1/5] [Support] Add KnownBits::computeForSubBorrow * Implements computeForSubBorrow as alias for computeforAddCarry. Borrow is expected to be 1-bit wide. * Adds exhaustive unit test. --- llvm/include/llvm/Support/KnownBits.h| 4 +++ llvm/lib/Support/KnownBits.cpp | 12 + llvm/unittests/Support/KnownBitsTest.cpp | 31 3 files changed, 47 insertions(+) diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h index 8462aa11202d5d7..711ca8c12129a1b 100644 --- a/llvm/include/llvm/Support/KnownBits.h +++ b/llvm/include/llvm/Support/KnownBits.h @@ -332,6 +332,10 @@ struct KnownBits { static KnownBits computeForAddSub(bool Add, bool NSW, const KnownBits &LHS, KnownBits RHS); + /// Compute known bits results from subtracting RHS from LHS. + static KnownBits computeForSubBorrow(const KnownBits &LHS, KnownBits RHS, + const KnownBits &Borrow); + /// Compute knownbits resulting from llvm.sadd.sat(LHS, RHS) static KnownBits sadd_sat(const KnownBits &LHS, const KnownBits &RHS); diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp index 097c22d33dd12ba..99ac50a34666fce 100644 --- a/llvm/lib/Support/KnownBits.cpp +++ b/llvm/lib/Support/KnownBits.cpp @@ -85,6 +85,18 @@ KnownBits KnownBits::computeForAddSub(bool Add, bool NSW, return KnownOut; } +KnownBits KnownBits::computeForSubBorrow(const KnownBits &LHS, KnownBits RHS, + const KnownBits &Borrow) { + assert(Borrow.getBitWidth() == 1 && "Borrow must be 1-bit"); + + // LHS - RHS = LHS + ~RHS + 1 + // Carry 1 - Borrow in ::computeForAddCarry + std::swap(RHS.Zero, RHS.One); + return ::computeForAddCarry(LHS, RHS, + /*CarryZero*/ Borrow.One.getBoolValue(), + /*CarryOne*/ Borrow.Zero.getBoolValue()); +} + KnownBits KnownBits::sextInReg(unsigned SrcBitWidth) const { unsigned BitWidth = getBitWidth(); assert(0 < SrcBitWidth && SrcBitWidth <= BitWidth && diff --git a/llvm/unittests/Support/KnownBitsTest.cpp b/llvm/unittests/Support/KnownBitsTest.cpp index 9d184beea3ba9e9..5597d69ab248d23 100644 --- a/llvm/unittests/Support/KnownBitsTest.cpp +++ b/llvm/unittests/Support/KnownBitsTest.cpp @@ -213,6 +213,37 @@ TEST(KnownBitsTest, AddSubExhaustive) { TestAddSubExhaustive(false); } +TEST(KnownBitsTest, SubBorrowExhaustive) { + unsigned Bits = 4; + ForeachKnownBits(Bits, [&](const KnownBits &Known1) { +ForeachKnownBits(Bits, [&](const KnownBits &Known2) { + ForeachKnownBits(1, [&](const KnownBits &KnownBorrow) { +// Explicitly compute known bits of the addition by trying all +// possibilities. +KnownBits Known(Bits); +Known.Zero.setAllBits(); +Known.One.setAllBits(); +ForeachNumInKnownBits(Known1, [&](const APInt &N1) { + ForeachNumInKnownBits(Known2, [&](const APInt &N2) { +ForeachNumInKnownBits(KnownBorrow, [&](const APInt &Borrow) { + APInt Sub = N1 - N2; + if (Borrow.getBoolValue()) +--Sub; + + Known.One &= Sub; + Known.Zero &= ~Sub; +}); + }); +}); + +KnownBits KnownComputed = +KnownBits::computeForSubBorrow(Known1, Known2, KnownBorrow); +EXPECT_EQ(Known, KnownComputed); + }); +}); + }); +} + TEST(KnownBitsTest, BinaryExhaustive) { testBinaryOpExhaustive( [](const KnownBits &Known1, const KnownBits &Known2) { >From f84c882cf429df238054d88ee07e41a08ae3fd6c Mon Sep 17 00:00:00 2001 From: Christian Kissig Date: Tue, 26 Sep 2023 18:02:49 + Subject: [PATCH 2/5] [CodeGen] Implement USUBC, USUBO_CARRY, and SSUBO_CARRY with KnownBits::computeForSubBorrow --- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 12 ++ .../CodeGen/AArch64SelectionDAGTest.cpp | 24 +++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index cd21af770e1a4d9..ab3e9b4bdc67402 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3732,14 +3732,18 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts, assert(Op.getResNo() == 0 && "We only compute knownbits for the difference here."); -// TODO: Compute influence of the carry operand. +// With UADDO_CARRY and SSUBO_CARRY a borrow bit may be added in. +KnownBits Borrow(1); if (Opcode == ISD::USUBO_CARRY || Opcode == ISD:
[Lldb-commits] [lldb] [Support] Add KnownBits::computeForSubBorrow (PR #67788)
https://github.com/christiankissig updated https://github.com/llvm/llvm-project/pull/67788 >From 5d86936c3a48c613460983c980271fcab8128b75 Mon Sep 17 00:00:00 2001 From: Christian Kissig Date: Tue, 26 Sep 2023 12:18:59 + Subject: [PATCH 1/5] [Support] Add KnownBits::computeForSubBorrow * Implements computeForSubBorrow as alias for computeforAddCarry. Borrow is expected to be 1-bit wide. * Adds exhaustive unit test. --- llvm/include/llvm/Support/KnownBits.h| 4 +++ llvm/lib/Support/KnownBits.cpp | 12 + llvm/unittests/Support/KnownBitsTest.cpp | 31 3 files changed, 47 insertions(+) diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h index 8462aa11202d5d7..711ca8c12129a1b 100644 --- a/llvm/include/llvm/Support/KnownBits.h +++ b/llvm/include/llvm/Support/KnownBits.h @@ -332,6 +332,10 @@ struct KnownBits { static KnownBits computeForAddSub(bool Add, bool NSW, const KnownBits &LHS, KnownBits RHS); + /// Compute known bits results from subtracting RHS from LHS. + static KnownBits computeForSubBorrow(const KnownBits &LHS, KnownBits RHS, + const KnownBits &Borrow); + /// Compute knownbits resulting from llvm.sadd.sat(LHS, RHS) static KnownBits sadd_sat(const KnownBits &LHS, const KnownBits &RHS); diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp index 097c22d33dd12ba..99ac50a34666fce 100644 --- a/llvm/lib/Support/KnownBits.cpp +++ b/llvm/lib/Support/KnownBits.cpp @@ -85,6 +85,18 @@ KnownBits KnownBits::computeForAddSub(bool Add, bool NSW, return KnownOut; } +KnownBits KnownBits::computeForSubBorrow(const KnownBits &LHS, KnownBits RHS, + const KnownBits &Borrow) { + assert(Borrow.getBitWidth() == 1 && "Borrow must be 1-bit"); + + // LHS - RHS = LHS + ~RHS + 1 + // Carry 1 - Borrow in ::computeForAddCarry + std::swap(RHS.Zero, RHS.One); + return ::computeForAddCarry(LHS, RHS, + /*CarryZero*/ Borrow.One.getBoolValue(), + /*CarryOne*/ Borrow.Zero.getBoolValue()); +} + KnownBits KnownBits::sextInReg(unsigned SrcBitWidth) const { unsigned BitWidth = getBitWidth(); assert(0 < SrcBitWidth && SrcBitWidth <= BitWidth && diff --git a/llvm/unittests/Support/KnownBitsTest.cpp b/llvm/unittests/Support/KnownBitsTest.cpp index 9d184beea3ba9e9..5597d69ab248d23 100644 --- a/llvm/unittests/Support/KnownBitsTest.cpp +++ b/llvm/unittests/Support/KnownBitsTest.cpp @@ -213,6 +213,37 @@ TEST(KnownBitsTest, AddSubExhaustive) { TestAddSubExhaustive(false); } +TEST(KnownBitsTest, SubBorrowExhaustive) { + unsigned Bits = 4; + ForeachKnownBits(Bits, [&](const KnownBits &Known1) { +ForeachKnownBits(Bits, [&](const KnownBits &Known2) { + ForeachKnownBits(1, [&](const KnownBits &KnownBorrow) { +// Explicitly compute known bits of the addition by trying all +// possibilities. +KnownBits Known(Bits); +Known.Zero.setAllBits(); +Known.One.setAllBits(); +ForeachNumInKnownBits(Known1, [&](const APInt &N1) { + ForeachNumInKnownBits(Known2, [&](const APInt &N2) { +ForeachNumInKnownBits(KnownBorrow, [&](const APInt &Borrow) { + APInt Sub = N1 - N2; + if (Borrow.getBoolValue()) +--Sub; + + Known.One &= Sub; + Known.Zero &= ~Sub; +}); + }); +}); + +KnownBits KnownComputed = +KnownBits::computeForSubBorrow(Known1, Known2, KnownBorrow); +EXPECT_EQ(Known, KnownComputed); + }); +}); + }); +} + TEST(KnownBitsTest, BinaryExhaustive) { testBinaryOpExhaustive( [](const KnownBits &Known1, const KnownBits &Known2) { >From f84c882cf429df238054d88ee07e41a08ae3fd6c Mon Sep 17 00:00:00 2001 From: Christian Kissig Date: Tue, 26 Sep 2023 18:02:49 + Subject: [PATCH 2/5] [CodeGen] Implement USUBC, USUBO_CARRY, and SSUBO_CARRY with KnownBits::computeForSubBorrow --- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 12 ++ .../CodeGen/AArch64SelectionDAGTest.cpp | 24 +++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index cd21af770e1a4d9..ab3e9b4bdc67402 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3732,14 +3732,18 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts, assert(Op.getResNo() == 0 && "We only compute knownbits for the difference here."); -// TODO: Compute influence of the carry operand. +// With UADDO_CARRY and SSUBO_CARRY a borrow bit may be added in. +KnownBits Borrow(1); if (Opcode == ISD::USUBO_CARRY || Opcode == ISD:
[Lldb-commits] [lldb] [Support] Add KnownBits::computeForSubBorrow (PR #67788)
https://github.com/christiankissig updated https://github.com/llvm/llvm-project/pull/67788 >From 5d86936c3a48c613460983c980271fcab8128b75 Mon Sep 17 00:00:00 2001 From: Christian Kissig Date: Tue, 26 Sep 2023 12:18:59 + Subject: [PATCH 1/5] [Support] Add KnownBits::computeForSubBorrow * Implements computeForSubBorrow as alias for computeforAddCarry. Borrow is expected to be 1-bit wide. * Adds exhaustive unit test. --- llvm/include/llvm/Support/KnownBits.h| 4 +++ llvm/lib/Support/KnownBits.cpp | 12 + llvm/unittests/Support/KnownBitsTest.cpp | 31 3 files changed, 47 insertions(+) diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h index 8462aa11202d5d7..711ca8c12129a1b 100644 --- a/llvm/include/llvm/Support/KnownBits.h +++ b/llvm/include/llvm/Support/KnownBits.h @@ -332,6 +332,10 @@ struct KnownBits { static KnownBits computeForAddSub(bool Add, bool NSW, const KnownBits &LHS, KnownBits RHS); + /// Compute known bits results from subtracting RHS from LHS. + static KnownBits computeForSubBorrow(const KnownBits &LHS, KnownBits RHS, + const KnownBits &Borrow); + /// Compute knownbits resulting from llvm.sadd.sat(LHS, RHS) static KnownBits sadd_sat(const KnownBits &LHS, const KnownBits &RHS); diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp index 097c22d33dd12ba..99ac50a34666fce 100644 --- a/llvm/lib/Support/KnownBits.cpp +++ b/llvm/lib/Support/KnownBits.cpp @@ -85,6 +85,18 @@ KnownBits KnownBits::computeForAddSub(bool Add, bool NSW, return KnownOut; } +KnownBits KnownBits::computeForSubBorrow(const KnownBits &LHS, KnownBits RHS, + const KnownBits &Borrow) { + assert(Borrow.getBitWidth() == 1 && "Borrow must be 1-bit"); + + // LHS - RHS = LHS + ~RHS + 1 + // Carry 1 - Borrow in ::computeForAddCarry + std::swap(RHS.Zero, RHS.One); + return ::computeForAddCarry(LHS, RHS, + /*CarryZero*/ Borrow.One.getBoolValue(), + /*CarryOne*/ Borrow.Zero.getBoolValue()); +} + KnownBits KnownBits::sextInReg(unsigned SrcBitWidth) const { unsigned BitWidth = getBitWidth(); assert(0 < SrcBitWidth && SrcBitWidth <= BitWidth && diff --git a/llvm/unittests/Support/KnownBitsTest.cpp b/llvm/unittests/Support/KnownBitsTest.cpp index 9d184beea3ba9e9..5597d69ab248d23 100644 --- a/llvm/unittests/Support/KnownBitsTest.cpp +++ b/llvm/unittests/Support/KnownBitsTest.cpp @@ -213,6 +213,37 @@ TEST(KnownBitsTest, AddSubExhaustive) { TestAddSubExhaustive(false); } +TEST(KnownBitsTest, SubBorrowExhaustive) { + unsigned Bits = 4; + ForeachKnownBits(Bits, [&](const KnownBits &Known1) { +ForeachKnownBits(Bits, [&](const KnownBits &Known2) { + ForeachKnownBits(1, [&](const KnownBits &KnownBorrow) { +// Explicitly compute known bits of the addition by trying all +// possibilities. +KnownBits Known(Bits); +Known.Zero.setAllBits(); +Known.One.setAllBits(); +ForeachNumInKnownBits(Known1, [&](const APInt &N1) { + ForeachNumInKnownBits(Known2, [&](const APInt &N2) { +ForeachNumInKnownBits(KnownBorrow, [&](const APInt &Borrow) { + APInt Sub = N1 - N2; + if (Borrow.getBoolValue()) +--Sub; + + Known.One &= Sub; + Known.Zero &= ~Sub; +}); + }); +}); + +KnownBits KnownComputed = +KnownBits::computeForSubBorrow(Known1, Known2, KnownBorrow); +EXPECT_EQ(Known, KnownComputed); + }); +}); + }); +} + TEST(KnownBitsTest, BinaryExhaustive) { testBinaryOpExhaustive( [](const KnownBits &Known1, const KnownBits &Known2) { >From f84c882cf429df238054d88ee07e41a08ae3fd6c Mon Sep 17 00:00:00 2001 From: Christian Kissig Date: Tue, 26 Sep 2023 18:02:49 + Subject: [PATCH 2/5] [CodeGen] Implement USUBC, USUBO_CARRY, and SSUBO_CARRY with KnownBits::computeForSubBorrow --- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 12 ++ .../CodeGen/AArch64SelectionDAGTest.cpp | 24 +++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index cd21af770e1a4d9..ab3e9b4bdc67402 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3732,14 +3732,18 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts, assert(Op.getResNo() == 0 && "We only compute knownbits for the difference here."); -// TODO: Compute influence of the carry operand. +// With UADDO_CARRY and SSUBO_CARRY a borrow bit may be added in. +KnownBits Borrow(1); if (Opcode == ISD::USUBO_CARRY || Opcode == ISD:
[Lldb-commits] [lldb] [Support] Add KnownBits::computeForSubBorrow (PR #67788)
https://github.com/christiankissig updated https://github.com/llvm/llvm-project/pull/67788 >From 5d86936c3a48c613460983c980271fcab8128b75 Mon Sep 17 00:00:00 2001 From: Christian Kissig Date: Tue, 26 Sep 2023 12:18:59 + Subject: [PATCH 1/6] [Support] Add KnownBits::computeForSubBorrow * Implements computeForSubBorrow as alias for computeforAddCarry. Borrow is expected to be 1-bit wide. * Adds exhaustive unit test. --- llvm/include/llvm/Support/KnownBits.h| 4 +++ llvm/lib/Support/KnownBits.cpp | 12 + llvm/unittests/Support/KnownBitsTest.cpp | 31 3 files changed, 47 insertions(+) diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h index 8462aa11202d5d7..711ca8c12129a1b 100644 --- a/llvm/include/llvm/Support/KnownBits.h +++ b/llvm/include/llvm/Support/KnownBits.h @@ -332,6 +332,10 @@ struct KnownBits { static KnownBits computeForAddSub(bool Add, bool NSW, const KnownBits &LHS, KnownBits RHS); + /// Compute known bits results from subtracting RHS from LHS. + static KnownBits computeForSubBorrow(const KnownBits &LHS, KnownBits RHS, + const KnownBits &Borrow); + /// Compute knownbits resulting from llvm.sadd.sat(LHS, RHS) static KnownBits sadd_sat(const KnownBits &LHS, const KnownBits &RHS); diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp index 097c22d33dd12ba..99ac50a34666fce 100644 --- a/llvm/lib/Support/KnownBits.cpp +++ b/llvm/lib/Support/KnownBits.cpp @@ -85,6 +85,18 @@ KnownBits KnownBits::computeForAddSub(bool Add, bool NSW, return KnownOut; } +KnownBits KnownBits::computeForSubBorrow(const KnownBits &LHS, KnownBits RHS, + const KnownBits &Borrow) { + assert(Borrow.getBitWidth() == 1 && "Borrow must be 1-bit"); + + // LHS - RHS = LHS + ~RHS + 1 + // Carry 1 - Borrow in ::computeForAddCarry + std::swap(RHS.Zero, RHS.One); + return ::computeForAddCarry(LHS, RHS, + /*CarryZero*/ Borrow.One.getBoolValue(), + /*CarryOne*/ Borrow.Zero.getBoolValue()); +} + KnownBits KnownBits::sextInReg(unsigned SrcBitWidth) const { unsigned BitWidth = getBitWidth(); assert(0 < SrcBitWidth && SrcBitWidth <= BitWidth && diff --git a/llvm/unittests/Support/KnownBitsTest.cpp b/llvm/unittests/Support/KnownBitsTest.cpp index 9d184beea3ba9e9..5597d69ab248d23 100644 --- a/llvm/unittests/Support/KnownBitsTest.cpp +++ b/llvm/unittests/Support/KnownBitsTest.cpp @@ -213,6 +213,37 @@ TEST(KnownBitsTest, AddSubExhaustive) { TestAddSubExhaustive(false); } +TEST(KnownBitsTest, SubBorrowExhaustive) { + unsigned Bits = 4; + ForeachKnownBits(Bits, [&](const KnownBits &Known1) { +ForeachKnownBits(Bits, [&](const KnownBits &Known2) { + ForeachKnownBits(1, [&](const KnownBits &KnownBorrow) { +// Explicitly compute known bits of the addition by trying all +// possibilities. +KnownBits Known(Bits); +Known.Zero.setAllBits(); +Known.One.setAllBits(); +ForeachNumInKnownBits(Known1, [&](const APInt &N1) { + ForeachNumInKnownBits(Known2, [&](const APInt &N2) { +ForeachNumInKnownBits(KnownBorrow, [&](const APInt &Borrow) { + APInt Sub = N1 - N2; + if (Borrow.getBoolValue()) +--Sub; + + Known.One &= Sub; + Known.Zero &= ~Sub; +}); + }); +}); + +KnownBits KnownComputed = +KnownBits::computeForSubBorrow(Known1, Known2, KnownBorrow); +EXPECT_EQ(Known, KnownComputed); + }); +}); + }); +} + TEST(KnownBitsTest, BinaryExhaustive) { testBinaryOpExhaustive( [](const KnownBits &Known1, const KnownBits &Known2) { >From f84c882cf429df238054d88ee07e41a08ae3fd6c Mon Sep 17 00:00:00 2001 From: Christian Kissig Date: Tue, 26 Sep 2023 18:02:49 + Subject: [PATCH 2/6] [CodeGen] Implement USUBC, USUBO_CARRY, and SSUBO_CARRY with KnownBits::computeForSubBorrow --- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 12 ++ .../CodeGen/AArch64SelectionDAGTest.cpp | 24 +++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index cd21af770e1a4d9..ab3e9b4bdc67402 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3732,14 +3732,18 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts, assert(Op.getResNo() == 0 && "We only compute knownbits for the difference here."); -// TODO: Compute influence of the carry operand. +// With UADDO_CARRY and SSUBO_CARRY a borrow bit may be added in. +KnownBits Borrow(1); if (Opcode == ISD::USUBO_CARRY || Opcode == ISD:
[Lldb-commits] [lldb] [Support] Add KnownBits::computeForSubBorrow (PR #67788)
https://github.com/christiankissig updated https://github.com/llvm/llvm-project/pull/67788 >From 5d86936c3a48c613460983c980271fcab8128b75 Mon Sep 17 00:00:00 2001 From: Christian Kissig Date: Tue, 26 Sep 2023 12:18:59 + Subject: [PATCH 1/7] [Support] Add KnownBits::computeForSubBorrow * Implements computeForSubBorrow as alias for computeforAddCarry. Borrow is expected to be 1-bit wide. * Adds exhaustive unit test. --- llvm/include/llvm/Support/KnownBits.h| 4 +++ llvm/lib/Support/KnownBits.cpp | 12 + llvm/unittests/Support/KnownBitsTest.cpp | 31 3 files changed, 47 insertions(+) diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h index 8462aa11202d5d7..711ca8c12129a1b 100644 --- a/llvm/include/llvm/Support/KnownBits.h +++ b/llvm/include/llvm/Support/KnownBits.h @@ -332,6 +332,10 @@ struct KnownBits { static KnownBits computeForAddSub(bool Add, bool NSW, const KnownBits &LHS, KnownBits RHS); + /// Compute known bits results from subtracting RHS from LHS. + static KnownBits computeForSubBorrow(const KnownBits &LHS, KnownBits RHS, + const KnownBits &Borrow); + /// Compute knownbits resulting from llvm.sadd.sat(LHS, RHS) static KnownBits sadd_sat(const KnownBits &LHS, const KnownBits &RHS); diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp index 097c22d33dd12ba..99ac50a34666fce 100644 --- a/llvm/lib/Support/KnownBits.cpp +++ b/llvm/lib/Support/KnownBits.cpp @@ -85,6 +85,18 @@ KnownBits KnownBits::computeForAddSub(bool Add, bool NSW, return KnownOut; } +KnownBits KnownBits::computeForSubBorrow(const KnownBits &LHS, KnownBits RHS, + const KnownBits &Borrow) { + assert(Borrow.getBitWidth() == 1 && "Borrow must be 1-bit"); + + // LHS - RHS = LHS + ~RHS + 1 + // Carry 1 - Borrow in ::computeForAddCarry + std::swap(RHS.Zero, RHS.One); + return ::computeForAddCarry(LHS, RHS, + /*CarryZero*/ Borrow.One.getBoolValue(), + /*CarryOne*/ Borrow.Zero.getBoolValue()); +} + KnownBits KnownBits::sextInReg(unsigned SrcBitWidth) const { unsigned BitWidth = getBitWidth(); assert(0 < SrcBitWidth && SrcBitWidth <= BitWidth && diff --git a/llvm/unittests/Support/KnownBitsTest.cpp b/llvm/unittests/Support/KnownBitsTest.cpp index 9d184beea3ba9e9..5597d69ab248d23 100644 --- a/llvm/unittests/Support/KnownBitsTest.cpp +++ b/llvm/unittests/Support/KnownBitsTest.cpp @@ -213,6 +213,37 @@ TEST(KnownBitsTest, AddSubExhaustive) { TestAddSubExhaustive(false); } +TEST(KnownBitsTest, SubBorrowExhaustive) { + unsigned Bits = 4; + ForeachKnownBits(Bits, [&](const KnownBits &Known1) { +ForeachKnownBits(Bits, [&](const KnownBits &Known2) { + ForeachKnownBits(1, [&](const KnownBits &KnownBorrow) { +// Explicitly compute known bits of the addition by trying all +// possibilities. +KnownBits Known(Bits); +Known.Zero.setAllBits(); +Known.One.setAllBits(); +ForeachNumInKnownBits(Known1, [&](const APInt &N1) { + ForeachNumInKnownBits(Known2, [&](const APInt &N2) { +ForeachNumInKnownBits(KnownBorrow, [&](const APInt &Borrow) { + APInt Sub = N1 - N2; + if (Borrow.getBoolValue()) +--Sub; + + Known.One &= Sub; + Known.Zero &= ~Sub; +}); + }); +}); + +KnownBits KnownComputed = +KnownBits::computeForSubBorrow(Known1, Known2, KnownBorrow); +EXPECT_EQ(Known, KnownComputed); + }); +}); + }); +} + TEST(KnownBitsTest, BinaryExhaustive) { testBinaryOpExhaustive( [](const KnownBits &Known1, const KnownBits &Known2) { >From f84c882cf429df238054d88ee07e41a08ae3fd6c Mon Sep 17 00:00:00 2001 From: Christian Kissig Date: Tue, 26 Sep 2023 18:02:49 + Subject: [PATCH 2/7] [CodeGen] Implement USUBC, USUBO_CARRY, and SSUBO_CARRY with KnownBits::computeForSubBorrow --- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 12 ++ .../CodeGen/AArch64SelectionDAGTest.cpp | 24 +++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index cd21af770e1a4d9..ab3e9b4bdc67402 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3732,14 +3732,18 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts, assert(Op.getResNo() == 0 && "We only compute knownbits for the difference here."); -// TODO: Compute influence of the carry operand. +// With UADDO_CARRY and SSUBO_CARRY a borrow bit may be added in. +KnownBits Borrow(1); if (Opcode == ISD::USUBO_CARRY || Opcode == ISD: