diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2016-09-13 19:43:57 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2016-09-13 19:43:57 +0000 |
commit | e2e6cfee610bd8583cd8c95ea333403cc053118f (patch) | |
tree | 315268200035c38596e8e2343b9e970752a35342 /llvm/lib/Transforms | |
parent | ce7a9a47b278584cf7bc13d8755a9198a24e4669 (diff) | |
download | bcm5719-llvm-e2e6cfee610bd8583cd8c95ea333403cc053118f.tar.gz bcm5719-llvm-e2e6cfee610bd8583cd8c95ea333403cc053118f.zip |
Reapply "InstCombine: Reduce trunc (shl x, K) width."
This reapplies r272987 with a fix for infinitely looping
when the truncated value is another shift of a constant.
llvm-svn: 281379
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 926019e9341..f05c714b661 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -532,14 +532,32 @@ Instruction *InstCombiner::visitTrunc(TruncInst &CI) { } } - // Transform "trunc (and X, cst)" -> "and (trunc X), cst" so long as the dest - // type isn't non-native. if (Src->hasOneUse() && isa<IntegerType>(SrcTy) && - ShouldChangeType(SrcTy, DestTy) && - match(Src, m_And(m_Value(A), m_ConstantInt(Cst)))) { - Value *NewTrunc = Builder->CreateTrunc(A, DestTy, A->getName() + ".tr"); - return BinaryOperator::CreateAnd(NewTrunc, - ConstantExpr::getTrunc(Cst, DestTy)); + ShouldChangeType(SrcTy, DestTy)) { + + // Transform "trunc (and X, cst)" -> "and (trunc X), cst" so long as the + // dest type is native. + if (match(Src, m_And(m_Value(A), m_ConstantInt(Cst)))) { + Value *NewTrunc = Builder->CreateTrunc(A, DestTy, A->getName() + ".tr"); + return BinaryOperator::CreateAnd(NewTrunc, + ConstantExpr::getTrunc(Cst, DestTy)); + } + + // Transform "trunc (shl X, cst)" -> "shl (trunc X), cst" so long as the + // dest type is native and cst < dest size. + if (match(Src, m_Shl(m_Value(A), m_ConstantInt(Cst))) && + !match(A, m_Shr(m_Value(), m_Constant()))) { + // Skip shifts of shift by constants. It undoes a combine in + // FoldShiftByConstant and is the extend in reg pattern. + const unsigned DestSize = DestTy->getScalarSizeInBits(); + if (Cst->getValue().ult(DestSize)) { + Value *NewTrunc = Builder->CreateTrunc(A, DestTy, A->getName() + ".tr"); + + return BinaryOperator::Create( + Instruction::Shl, NewTrunc, + ConstantInt::get(DestTy, Cst->getValue().trunc(DestSize))); + } + } } if (Instruction *I = foldVecTruncToExtElt(CI, *this, DL)) |