diff options
author | Amjad Aboud <amjad.aboud@intel.com> | 2017-08-18 22:56:55 +0000 |
---|---|---|
committer | Amjad Aboud <amjad.aboud@intel.com> | 2017-08-18 22:56:55 +0000 |
commit | 88ffa3afe289b02889957070ba6ac132fd4f2ce4 (patch) | |
tree | c47525f9947988d97a38d0dc1fec9db93302e61b | |
parent | 0aaf8c16acad178afa75f50252ea58a15d852bd9 (diff) | |
download | bcm5719-llvm-88ffa3afe289b02889957070ba6ac132fd4f2ce4.tar.gz bcm5719-llvm-88ffa3afe289b02889957070ba6ac132fd4f2ce4.zip |
[InstCombine] Teach ComputeNumSignBitsImpl to handle integer multiply instruction.
Differential Revision: https://reviews.llvm.org/D36679
llvm-svn: 311206
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 11 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/trunc.ll | 15 |
2 files changed, 26 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index d73e5f25119..d936c48a3a6 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2196,6 +2196,17 @@ static unsigned ComputeNumSignBitsImpl(const Value *V, unsigned Depth, if (Tmp == 1) return 1; // Early out. return std::min(Tmp, Tmp2)-1; + case Instruction::Mul: { + // The output of the Mul can be at most twice the valid bits in the inputs. + unsigned SignBitsOp0 = ComputeNumSignBits(U->getOperand(0), Depth + 1, Q); + if (SignBitsOp0 == 1) return 1; // Early out. + unsigned SignBitsOp1 = ComputeNumSignBits(U->getOperand(1), Depth + 1, Q); + if (SignBitsOp1 == 1) return 1; + unsigned OutValidBits = + (TyBits - SignBitsOp0 + 1) + (TyBits - SignBitsOp1 + 1); + return OutValidBits > TyBits ? 1 : TyBits - OutValidBits + 1; + } + case Instruction::PHI: { const PHINode *PN = cast<PHINode>(U); unsigned NumIncomingValues = PN->getNumIncomingValues(); diff --git a/llvm/test/Transforms/InstCombine/trunc.ll b/llvm/test/Transforms/InstCombine/trunc.ll index 40956d3ff8c..0d071da542a 100644 --- a/llvm/test/Transforms/InstCombine/trunc.ll +++ b/llvm/test/Transforms/InstCombine/trunc.ll @@ -89,6 +89,21 @@ define i32 @test6(i64 %A) { ret i32 %D } +define i16 @ashr_mul(i8 %X, i8 %Y) { +; CHECK-LABEL: @ashr_mul( +; CHECK-NEXT: [[A:%.*]] = sext i8 %X to i16 +; CHECK-NEXT: [[B:%.*]] = sext i8 %Y to i16 +; CHECK-NEXT: [[C:%.*]] = mul nsw i16 [[A]], [[B]] +; CHECK-NEXT: [[D:%.*]] = ashr i16 [[C]], 8 +; CHECK-NEXT: ret i16 [[D]] + %A = sext i8 %X to i20 + %B = sext i8 %Y to i20 + %C = mul i20 %A, %B + %D = ashr i20 %C, 8 + %E = trunc i20 %D to i16 + ret i16 %E +} + define i32 @trunc_ashr(i32 %X) { ; CHECK-LABEL: @trunc_ashr( ; CHECK-NEXT: [[B:%.*]] = or i32 [[X:%.*]], -2147483648 |