summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/KnownBits.cpp
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-04-12 18:18:08 +0000
committerNikita Popov <nikita.ppv@gmail.com>2019-04-12 18:18:08 +0000
commit7671fc71f62a7387c06742c569fe17608796e8f2 (patch)
treec219b1b1ed382fe7fe62a2470cbbffe205b89b9a /llvm/lib/Support/KnownBits.cpp
parent7a60cd38af5563ebe4efa6f1544dca5a5ebebbee (diff)
downloadbcm5719-llvm-7671fc71f62a7387c06742c569fe17608796e8f2.tar.gz
bcm5719-llvm-7671fc71f62a7387c06742c569fe17608796e8f2.zip
[KnownBits] Add computeForAddCarry()
This is for D60460. computeForAddSub() essentially already supports carries because it has to deal with subtractions. This revision extracts a lower-level computeForAddCarry() function, which allows computing the known bits for add (carry known zero), sub (carry known one) and addcarry (carry unknown). As we don't seem to have any yet, I've added a unit test file for KnownBits and exhaustive tests for the new computeForAddCarry() functionality, as well the existing computeForAddSub() function. Differential Revision: https://reviews.llvm.org/D60522 llvm-svn: 358297
Diffstat (limited to 'llvm/lib/Support/KnownBits.cpp')
-rw-r--r--llvm/lib/Support/KnownBits.cpp43
1 files changed, 31 insertions, 12 deletions
diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp
index 9988314fabb..a6c591fca31 100644
--- a/llvm/lib/Support/KnownBits.cpp
+++ b/llvm/lib/Support/KnownBits.cpp
@@ -15,18 +15,14 @@
using namespace llvm;
-KnownBits KnownBits::computeForAddSub(bool Add, bool NSW,
- const KnownBits &LHS, KnownBits RHS) {
- // Carry in a 1 for a subtract, rather than 0.
- bool CarryIn = false;
- if (!Add) {
- // Sum = LHS + ~RHS + 1
- std::swap(RHS.Zero, RHS.One);
- CarryIn = true;
- }
+static KnownBits computeForAddCarry(
+ const KnownBits &LHS, const KnownBits &RHS,
+ bool CarryZero, bool CarryOne) {
+ assert(!(CarryZero && CarryOne) &&
+ "Carry can't be zero and one at the same time");
- APInt PossibleSumZero = ~LHS.Zero + ~RHS.Zero + CarryIn;
- APInt PossibleSumOne = LHS.One + RHS.One + CarryIn;
+ APInt PossibleSumZero = ~LHS.Zero + ~RHS.Zero + !CarryZero;
+ APInt PossibleSumOne = LHS.One + RHS.One + CarryOne;
// Compute known bits of the carry.
APInt CarryKnownZero = ~(PossibleSumZero ^ LHS.Zero ^ RHS.Zero);
@@ -45,9 +41,32 @@ KnownBits KnownBits::computeForAddSub(bool Add, bool NSW,
KnownBits KnownOut;
KnownOut.Zero = ~std::move(PossibleSumZero) & Known;
KnownOut.One = std::move(PossibleSumOne) & Known;
+ return KnownOut;
+}
+
+KnownBits KnownBits::computeForAddCarry(
+ const KnownBits &LHS, const KnownBits &RHS, const KnownBits &Carry) {
+ assert(Carry.getBitWidth() == 1 && "Carry must be 1-bit");
+ return ::computeForAddCarry(
+ LHS, RHS, Carry.Zero.getBoolValue(), Carry.One.getBoolValue());
+}
+
+KnownBits KnownBits::computeForAddSub(bool Add, bool NSW,
+ const KnownBits &LHS, KnownBits RHS) {
+ KnownBits KnownOut;
+ if (Add) {
+ // Sum = LHS + RHS + 0
+ KnownOut = ::computeForAddCarry(
+ LHS, RHS, /*CarryZero*/true, /*CarryOne*/false);
+ } else {
+ // Sum = LHS + ~RHS + 1
+ std::swap(RHS.Zero, RHS.One);
+ KnownOut = ::computeForAddCarry(
+ LHS, RHS, /*CarryZero*/false, /*CarryOne*/true);
+ }
// Are we still trying to solve for the sign bit?
- if (!Known.isSignBitSet()) {
+ if (!KnownOut.isNegative() && !KnownOut.isNonNegative()) {
if (NSW) {
// Adding two non-negative numbers, or subtracting a negative number from
// a non-negative one, can't wrap into negative.
OpenPOWER on IntegriCloud