Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[KnownBits][ValueTracking] Move the math for calculating known bits f…
…or add/sub into a static method in KnownBits object I want to reuse this code in SimplifyDemandedBits handling of Add/Sub. This will make that easier. Wonder if we should use it in SelectionDAG's computeKnownBits too. Differential Revision: https://reviews.llvm.org/D36433 llvm-svn: 310378
- Loading branch information
Showing
4 changed files
with
71 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
//===-- 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. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file contains a class for representing known zeros and ones used by | ||
// computeKnownBits. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "llvm/Support/KnownBits.h" | ||
|
||
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; | ||
} | ||
|
||
APInt PossibleSumZero = ~LHS.Zero + ~RHS.Zero + CarryIn; | ||
APInt PossibleSumOne = LHS.One + RHS.One + CarryIn; | ||
|
||
// Compute known bits of the carry. | ||
APInt CarryKnownZero = ~(PossibleSumZero ^ LHS.Zero ^ RHS.Zero); | ||
APInt CarryKnownOne = PossibleSumOne ^ LHS.One ^ RHS.One; | ||
|
||
// Compute set of known bits (where all three relevant bits are known). | ||
APInt LHSKnownUnion = LHS.Zero | LHS.One; | ||
APInt RHSKnownUnion = RHS.Zero | RHS.One; | ||
APInt CarryKnownUnion = std::move(CarryKnownZero) | CarryKnownOne; | ||
APInt Known = std::move(LHSKnownUnion) & RHSKnownUnion & CarryKnownUnion; | ||
|
||
assert((PossibleSumZero & Known) == (PossibleSumOne & Known) && | ||
"known bits of sum differ"); | ||
|
||
// Compute known bits of the result. | ||
KnownBits KnownOut; | ||
KnownOut.Zero = ~std::move(PossibleSumZero) & Known; | ||
KnownOut.One = std::move(PossibleSumOne) & Known; | ||
|
||
// Are we still trying to solve for the sign bit? | ||
if (!Known.isSignBitSet()) { | ||
if (NSW) { | ||
// Adding two non-negative numbers, or subtracting a negative number from | ||
// a non-negative one, can't wrap into negative. | ||
if (LHS.isNonNegative() && RHS.isNonNegative()) | ||
KnownOut.makeNonNegative(); | ||
// Adding two negative numbers, or subtracting a non-negative number from | ||
// a negative one, can't wrap into non-negative. | ||
else if (LHS.isNegative() && RHS.isNegative()) | ||
KnownOut.makeNegative(); | ||
} | ||
} | ||
|
||
return KnownOut; | ||
} |