aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2018-05-25 19:18:09 +0000
committerCraig Topper <craig.topper@intel.com>2018-05-25 19:18:09 +0000
commit8f77dcadffe06502027bdb2701cd3653ecca919b (patch)
tree2160de8e624aec9ef6544f162d85e085fdb397a1 /llvm/lib/Analysis/ValueTracking.cpp
parent39bf7d551b548f3f2c831fc20ee847826152ce86 (diff)
downloadllvm-8f77dcadffe06502027bdb2701cd3653ecca919b.zip
llvm-8f77dcadffe06502027bdb2701cd3653ecca919b.tar.gz
llvm-8f77dcadffe06502027bdb2701cd3653ecca919b.tar.bz2
Recommit r333226 "[ValueTracking] Teach computeKnownBits that the result of an absolute value pattern that uses nsw flag is always positive."
Libfuzzer tests have been fixed to prevent being optimized. Original commit message: 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. N Differential Revision: https://reviews.llvm.org/D47041 llvm-svn: 333300
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.