aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Support/KnownBits.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Support/KnownBits.cpp')
-rw-r--r--contrib/llvm/lib/Support/KnownBits.cpp50
1 files changed, 34 insertions, 16 deletions
diff --git a/contrib/llvm/lib/Support/KnownBits.cpp b/contrib/llvm/lib/Support/KnownBits.cpp
index ac790ebed352..a6c591fca312 100644
--- a/contrib/llvm/lib/Support/KnownBits.cpp
+++ b/contrib/llvm/lib/Support/KnownBits.cpp
@@ -1,9 +1,8 @@
//===-- KnownBits.cpp - Stores known zeros/ones ---------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -16,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);
@@ -46,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.