aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-01-02 07:29:47 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-01-02 07:29:47 +0000
commitc8a576b5c03de6bec83aa7dfe5f70adb5e0bafe9 (patch)
treea13f537fbf6ea3f7050cb63b66780c5e514ba196 /llvm/lib/Analysis/ValueTracking.cpp
parent491331aca8389555070069699d92a9674c413b00 (diff)
downloadllvm-c8a576b5c03de6bec83aa7dfe5f70adb5e0bafe9.zip
llvm-c8a576b5c03de6bec83aa7dfe5f70adb5e0bafe9.tar.gz
llvm-c8a576b5c03de6bec83aa7dfe5f70adb5e0bafe9.tar.bz2
InstCombine: Detect when llvm.umul.with.overflow always overflows
We know overflow always occurs if both ~LHSKnownZero * ~RHSKnownZero and LHSKnownOne * RHSKnownOne overflow. llvm-svn: 225077
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp23
1 files changed, 16 insertions, 7 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index cb1e285..3a0efa7 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2686,10 +2686,11 @@ OverflowResult llvm::computeOverflowForUnsignedMul(Value *LHS, Value *RHS,
// Ref: "Hacker's Delight" by Henry Warren
unsigned BitWidth = LHS->getType()->getScalarSizeInBits();
APInt LHSKnownZero(BitWidth, 0);
+ APInt LHSKnownOne(BitWidth, 0);
APInt RHSKnownZero(BitWidth, 0);
- APInt TmpKnownOne(BitWidth, 0);
- computeKnownBits(LHS, LHSKnownZero, TmpKnownOne, DL, /*Depth=*/0, AT, CxtI, DT);
- computeKnownBits(RHS, RHSKnownZero, TmpKnownOne, DL, /*Depth=*/0, AT, CxtI, DT);
+ APInt RHSKnownOne(BitWidth, 0);
+ computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, DL, /*Depth=*/0, AT, CxtI, DT);
+ computeKnownBits(RHS, RHSKnownZero, RHSKnownOne, DL, /*Depth=*/0, AT, CxtI, DT);
// Note that underestimating the number of zero bits gives a more
// conservative answer.
unsigned ZeroBits = LHSKnownZero.countLeadingOnes() +
@@ -2705,9 +2706,17 @@ OverflowResult llvm::computeOverflowForUnsignedMul(Value *LHS, Value *RHS,
// We know the multiply operation doesn't overflow if the maximum values for
// each operand will not overflow after we multiply them together.
- bool Overflow;
- LHSMax.umul_ov(RHSMax, Overflow);
+ bool MaxOverflow;
+ LHSMax.umul_ov(RHSMax, MaxOverflow);
+ if (!MaxOverflow)
+ return OverflowResult::NeverOverflows;
+
+ // We know it always overflows if multiplying the smallest possible values for
+ // the operands also results in overflow.
+ bool MinOverflow;
+ LHSKnownOne.umul_ov(RHSKnownOne, MinOverflow);
+ if (MinOverflow)
+ return OverflowResult::AlwaysOverflows;
- return Overflow ? OverflowResult::MayOverflow
- : OverflowResult::NeverOverflows;
+ return OverflowResult::MayOverflow;
}