summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/KnownBits.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Support/KnownBits.cpp')
-rw-r--r--llvm/lib/Support/KnownBits.cpp23
1 files changed, 21 insertions, 2 deletions
diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp
index c33c3680825a..d72355dab6f1 100644
--- a/llvm/lib/Support/KnownBits.cpp
+++ b/llvm/lib/Support/KnownBits.cpp
@@ -231,8 +231,8 @@ KnownBits KnownBits::smin(const KnownBits &LHS, const KnownBits &RHS) {
return Flip(umax(Flip(LHS), Flip(RHS)));
}
-KnownBits KnownBits::absdiff(const KnownBits &LHS, const KnownBits &RHS) {
- // absdiff(LHS,RHS) = sub(umax(LHS,RHS), umin(LHS,RHS)).
+KnownBits KnownBits::abdu(const KnownBits &LHS, const KnownBits &RHS) {
+ // abdu(LHS,RHS) = sub(umax(LHS,RHS), umin(LHS,RHS)).
KnownBits UMaxValue = umax(LHS, RHS);
KnownBits UMinValue = umin(LHS, RHS);
KnownBits MinMaxDiff = computeForAddSub(/*Add=*/false, /*NSW=*/false,
@@ -250,6 +250,25 @@ KnownBits KnownBits::absdiff(const KnownBits &LHS, const KnownBits &RHS) {
return KnownAbsDiff;
}
+KnownBits KnownBits::abds(const KnownBits &LHS, const KnownBits &RHS) {
+ // abds(LHS,RHS) = sub(smax(LHS,RHS), smin(LHS,RHS)).
+ KnownBits SMaxValue = smax(LHS, RHS);
+ KnownBits SMinValue = smin(LHS, RHS);
+ KnownBits MinMaxDiff = computeForAddSub(/*Add=*/false, /*NSW=*/false,
+ /*NUW=*/false, SMaxValue, SMinValue);
+
+ // find the common bits between sub(LHS,RHS) and sub(RHS,LHS).
+ KnownBits Diff0 =
+ computeForAddSub(/*Add=*/false, /*NSW=*/false, /*NUW=*/false, LHS, RHS);
+ KnownBits Diff1 =
+ computeForAddSub(/*Add=*/false, /*NSW=*/false, /*NUW=*/false, RHS, LHS);
+ KnownBits SubDiff = Diff0.intersectWith(Diff1);
+
+ KnownBits KnownAbsDiff = MinMaxDiff.unionWith(SubDiff);
+ assert(!KnownAbsDiff.hasConflict() && "Bad Output");
+ return KnownAbsDiff;
+}
+
static unsigned getMaxShiftAmount(const APInt &MaxValue, unsigned BitWidth) {
if (isPowerOf2_32(BitWidth))
return MaxValue.extractBitsAsZExtValue(Log2_32(BitWidth), 0);