aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2018-05-24 21:22:51 +0000
committerCraig Topper <craig.topper@intel.com>2018-05-24 21:22:51 +0000
commit49f23fe349fb6ea36a61cbf01df87a76b06c02bb (patch)
treef23d36ddfad16846b63a519d86606eb0672d0374 /llvm/lib/Analysis/ValueTracking.cpp
parent6da6f433a04ae244adcd6184275bb6e1944b6ca2 (diff)
downloadllvm-49f23fe349fb6ea36a61cbf01df87a76b06c02bb.zip
llvm-49f23fe349fb6ea36a61cbf01df87a76b06c02bb.tar.gz
llvm-49f23fe349fb6ea36a61cbf01df87a76b06c02bb.tar.bz2
[ValueTracking] Teach computeKnownBits that the result of an absolute value pattern that uses nsw flag is always positive.
If the nsw flag is used in the absolute value then it is undefined for INT_MIN. For all other value it will produce a positive number. So we can assume the result is positive. This breaks some InstCombine abs/nabs combining tests because we simplify the second compare from known bits rather than as the whole pattern. Looks like we can probably fix it by adding a neg+abs/nabs combine to just swap the select operands. Need to check alive to make sure there are no corner cases. Differential Revision: https://reviews.llvm.org/D47041 llvm-svn: 333226
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp6
1 files changed, 6 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 7f33c67..5f5d1be 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1078,6 +1078,12 @@ static void computeKnownBitsFromOperator(const Operator *I, KnownBits &Known,
// leading zero bits.
MaxHighZeros =
std::max(Known.countMinLeadingZeros(), Known2.countMinLeadingZeros());
+ } else 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 (cast<Instruction>(RHS)->hasNoSignedWrap())
+ MaxHighZeros = 1;
}
// Only known if known in both the LHS and RHS.