aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorJay Foad <jay.foad@amd.com>2020-09-02 16:01:48 +0100
committerJay Foad <jay.foad@amd.com>2020-09-07 09:09:01 +0100
commit5350e1b5096aa4707aa525baf7398d93b4a4f1a5 (patch)
tree4896cf0b042cab5c52acb65acea4781f00f60b5d /llvm/lib/Analysis/ValueTracking.cpp
parent04ea680a8ccc4f9a4d7333cd712333960348c35b (diff)
downloadllvm-5350e1b5096aa4707aa525baf7398d93b4a4f1a5.zip
llvm-5350e1b5096aa4707aa525baf7398d93b4a4f1a5.tar.gz
llvm-5350e1b5096aa4707aa525baf7398d93b4a4f1a5.tar.bz2
[KnownBits] Implement accurate unsigned and signed max and min
Use the new implementation in ValueTracking, SelectionDAG and GlobalISel. Differential Revision: https://reviews.llvm.org/D87034
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp70
1 files changed, 26 insertions, 44 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 3a6ee35..6e5a719 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1212,59 +1212,41 @@ static void computeKnownBitsFromOperator(const Operator *I,
if (SelectPatternResult::isMinOrMax(SPF)) {
computeKnownBits(RHS, Known, Depth + 1, Q);
computeKnownBits(LHS, Known2, Depth + 1, Q);
- } else {
- computeKnownBits(I->getOperand(2), Known, Depth + 1, Q);
- computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
+ switch (SPF) {
+ default:
+ llvm_unreachable("Unhandled select pattern flavor!");
+ case SPF_SMAX:
+ Known = KnownBits::smax(Known, Known2);
+ break;
+ case SPF_SMIN:
+ Known = KnownBits::smin(Known, Known2);
+ break;
+ case SPF_UMAX:
+ Known = KnownBits::umax(Known, Known2);
+ break;
+ case SPF_UMIN:
+ Known = KnownBits::umin(Known, Known2);
+ break;
+ }
+ break;
}
- unsigned MaxHighOnes = 0;
- unsigned MaxHighZeros = 0;
- if (SPF == SPF_SMAX) {
- // If both sides are negative, the result is negative.
- if (Known.isNegative() && Known2.isNegative())
- // We can derive a lower bound on the result by taking the max of the
- // leading one bits.
- MaxHighOnes =
- std::max(Known.countMinLeadingOnes(), Known2.countMinLeadingOnes());
- // If either side is non-negative, the result is non-negative.
- else if (Known.isNonNegative() || Known2.isNonNegative())
- MaxHighZeros = 1;
- } else if (SPF == SPF_SMIN) {
- // If both sides are non-negative, the result is non-negative.
- if (Known.isNonNegative() && Known2.isNonNegative())
- // We can derive an upper bound on the result by taking the max of the
- // leading zero bits.
- MaxHighZeros = std::max(Known.countMinLeadingZeros(),
- Known2.countMinLeadingZeros());
- // If either side is negative, the result is negative.
- else if (Known.isNegative() || Known2.isNegative())
- MaxHighOnes = 1;
- } else if (SPF == SPF_UMAX) {
- // We can derive a lower bound on the result by taking the max of the
- // leading one bits.
- MaxHighOnes =
- std::max(Known.countMinLeadingOnes(), Known2.countMinLeadingOnes());
- } else if (SPF == SPF_UMIN) {
- // We can derive an upper bound on the result by taking the max of the
- // leading zero bits.
- MaxHighZeros =
- std::max(Known.countMinLeadingZeros(), Known2.countMinLeadingZeros());
- } else if (SPF == SPF_ABS) {
+ computeKnownBits(I->getOperand(2), Known, Depth + 1, Q);
+ computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
+
+ // Only known if known in both the LHS and RHS.
+ Known.One &= Known2.One;
+ Known.Zero &= Known2.Zero;
+
+ if (SPF == SPF_ABS) {
// RHS from matchSelectPattern returns the negation part of abs pattern.
// If the negate has an NSW flag we can assume the sign bit of the result
// will be 0 because that makes abs(INT_MIN) undefined.
if (match(RHS, m_Neg(m_Specific(LHS))) &&
Q.IIQ.hasNoSignedWrap(cast<Instruction>(RHS)))
- MaxHighZeros = 1;
+ Known.Zero.setSignBit();
}
- // Only known if known in both the LHS and RHS.
- Known.One &= Known2.One;
- Known.Zero &= Known2.Zero;
- if (MaxHighOnes > 0)
- Known.One.setHighBits(MaxHighOnes);
- if (MaxHighZeros > 0)
- Known.Zero.setHighBits(MaxHighZeros);
break;
}
case Instruction::FPTrunc: