aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-12-26 09:10:14 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-12-26 09:10:14 +0000
commit54c2ca25392d242fcf1e5cdc3d97737c8b002384 (patch)
tree5c6c018a438ea98ddc5274fd43f9d0f358ddba94 /llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
parentee9eef2fd865632d7ae8f8f8f05b37b2cc518afe (diff)
downloadllvm-54c2ca25392d242fcf1e5cdc3d97737c8b002384.zip
llvm-54c2ca25392d242fcf1e5cdc3d97737c8b002384.tar.gz
llvm-54c2ca25392d242fcf1e5cdc3d97737c8b002384.tar.bz2
InstCombe: Infer nsw for multiplies
We already utilize this logic for reducing overflow intrinsics, it makes sense to reuse it for normal multiplies as well. llvm-svn: 224847
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 3956869..5beaf00 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -123,6 +123,48 @@ static Constant *getLogBase2Vector(ConstantDataVector *CV) {
return ConstantVector::get(Elts);
}
+/// \brief Return true if we can prove that:
+/// (mul LHS, RHS) === (mul nsw LHS, RHS)
+bool InstCombiner::WillNotOverflowSignedMul(Value *LHS, Value *RHS,
+ Instruction *CxtI) {
+ // Multiplying n * m significant bits yields a result of n + m significant
+ // bits. If the total number of significant bits does not exceed the
+ // result bit width (minus 1), there is no overflow.
+ // This means if we have enough leading sign bits in the operands
+ // we can guarantee that the result does not overflow.
+ // Ref: "Hacker's Delight" by Henry Warren
+ unsigned BitWidth = LHS->getType()->getScalarSizeInBits();
+
+ // Note that underestimating the number of sign bits gives a more
+ // conservative answer.
+ unsigned SignBits = ComputeNumSignBits(LHS, 0, CxtI) +
+ ComputeNumSignBits(RHS, 0, CxtI);
+
+ // First handle the easy case: if we have enough sign bits there's
+ // definitely no overflow.
+ if (SignBits > BitWidth + 1)
+ return true;
+
+ // There are two ambiguous cases where there can be no overflow:
+ // SignBits == BitWidth + 1 and
+ // SignBits == BitWidth
+ // The second case is difficult to check, therefore we only handle the
+ // first case.
+ if (SignBits == BitWidth + 1) {
+ // It overflows only when both arguments are negative and the true
+ // product is exactly the minimum negative number.
+ // E.g. mul i16 with 17 sign bits: 0xff00 * 0xff80 = 0x8000
+ // For simplicity we just check if at least one side is not negative.
+ bool LHSNonNegative, LHSNegative;
+ bool RHSNonNegative, RHSNegative;
+ ComputeSignBit(LHS, LHSNonNegative, LHSNegative, /*Depth=*/0, CxtI);
+ ComputeSignBit(RHS, RHSNonNegative, RHSNegative, /*Depth=*/0, CxtI);
+ if (LHSNonNegative || RHSNonNegative)
+ return true;
+ }
+ return false;
+}
+
Instruction *InstCombiner::visitMul(BinaryOperator &I) {
bool Changed = SimplifyAssociativeOrCommutative(I);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
@@ -333,6 +375,11 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
}
}
+ if (!I.hasNoSignedWrap() && WillNotOverflowSignedMul(Op0, Op1, &I)) {
+ Changed = true;
+ I.setHasNoSignedWrap(true);
+ }
+
return Changed ? &I : nullptr;
}