diff options
author | Sanjay Patel <spatel@rotateright.com> | 2017-08-05 15:19:18 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2017-08-05 15:19:18 +0000 |
commit | 94da1de1cecf21cbcbc47972d5b780d7fdc7c63b (patch) | |
tree | 17f1e900911aaa94dc1a6a2ee28a3ad5f2b124ce /llvm/lib/Transforms | |
parent | d51a35e339b97786ba4712f2bfd09c3f9c1848a3 (diff) | |
download | bcm5719-llvm-94da1de1cecf21cbcbc47972d5b780d7fdc7c63b.tar.gz bcm5719-llvm-94da1de1cecf21cbcbc47972d5b780d7fdc7c63b.zip |
[InstCombine] refactor trunc(binop) transforms; NFCI
In addition to moving the shift transforms over, we may want to
detect too-wide rotate patterns here (PR34046).
llvm-svn: 310181
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 76 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineInternal.h | 2 |
2 files changed, 38 insertions, 40 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 566a143384d..3139cb33045 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -443,24 +443,49 @@ static Instruction *foldVecTruncToExtElt(TruncInst &Trunc, InstCombiner &IC) { return ExtractElementInst::Create(VecInput, IC.Builder.getInt32(Elt)); } -/// Try to narrow the width of bitwise logic instructions with constants. -Instruction *InstCombiner::shrinkBitwiseLogic(TruncInst &Trunc) { +/// Try to narrow the width of math or bitwise logic instructions by pulling a +/// truncate ahead of binary operators. +/// TODO: Transforms for truncated shifts should be moved into here. +Instruction *InstCombiner::narrowBinOp(TruncInst &Trunc) { Type *SrcTy = Trunc.getSrcTy(); Type *DestTy = Trunc.getType(); if (isa<IntegerType>(SrcTy) && !shouldChangeType(SrcTy, DestTy)) return nullptr; - BinaryOperator *LogicOp; - Constant *C; - if (!match(Trunc.getOperand(0), m_OneUse(m_BinOp(LogicOp))) || - !LogicOp->isBitwiseLogicOp() || - !match(LogicOp->getOperand(1), m_Constant(C))) + BinaryOperator *BinOp; + if (!match(Trunc.getOperand(0), m_OneUse(m_BinOp(BinOp)))) return nullptr; - // trunc (logic X, C) --> logic (trunc X, C') - Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy); - Value *NarrowOp0 = Builder.CreateTrunc(LogicOp->getOperand(0), DestTy); - return BinaryOperator::Create(LogicOp->getOpcode(), NarrowOp0, NarrowC); + switch (BinOp->getOpcode()) { + case Instruction::And: + case Instruction::Or: + case Instruction::Xor: + case Instruction::Add: + case Instruction::Mul: { + Constant *C; + if (match(BinOp->getOperand(1), m_Constant(C))) { + // trunc (binop X, C) --> binop (trunc X, C') + Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy); + Value *TruncX = Builder.CreateTrunc(BinOp->getOperand(0), DestTy); + return BinaryOperator::Create(BinOp->getOpcode(), TruncX, NarrowC); + } + break; + } + case Instruction::Sub: { + Constant *C; + if (match(BinOp->getOperand(0), m_Constant(C))) { + // trunc (binop C, X) --> binop (trunc C', X) + Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy); + Value *TruncX = Builder.CreateTrunc(BinOp->getOperand(1), DestTy); + return BinaryOperator::Create(BinOp->getOpcode(), NarrowC, TruncX); + } + break; + } + + default: break; + } + + return nullptr; } /// Try to narrow the width of a splat shuffle. This could be generalized to any @@ -558,33 +583,6 @@ Instruction *InstCombiner::visitTrunc(TruncInst &CI) { return new ICmpInst(ICmpInst::ICMP_NE, Src, Zero); } - if ((!isa<IntegerType>(SrcTy) || shouldChangeType(SrcTy, DestTy)) && - Src->hasOneUse()) { - // Add/sub/mul can always be narrowed if we're killing the high bits. - // If one operand is a constant, then we're not generating more - // instructions to perform the narrower math op. - Value *X; - Constant *C; - if (match(Src, m_Add(m_Value(X), m_Constant(C)))) { - // trunc(add X, C) --> add(trunc X, C') - Value *TruncX = Builder.CreateTrunc(X, DestTy); - Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy); - return BinaryOperator::CreateAdd(TruncX, NarrowC); - } - if (match(Src, m_Mul(m_Value(X), m_Constant(C)))) { - // trunc(mul X, C) --> mul(trunc X, C') - Value *TruncX = Builder.CreateTrunc(X, DestTy); - Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy); - return BinaryOperator::CreateMul(TruncX, NarrowC); - } - if (match(Src, m_Sub(m_Constant(C), m_Value(X)))) { - // trunc(sub C, X) --> sub(C', trunc X) - Value *TruncX = Builder.CreateTrunc(X, DestTy); - Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy); - return BinaryOperator::CreateSub(NarrowC, TruncX); - } - } - // FIXME: Maybe combine the next two transforms to handle the no cast case // more efficiently. Support vector types. Cleanup code by using m_OneUse. @@ -643,7 +641,7 @@ Instruction *InstCombiner::visitTrunc(TruncInst &CI) { } } - if (Instruction *I = shrinkBitwiseLogic(CI)) + if (Instruction *I = narrowBinOp(CI)) return I; if (Instruction *I = shrinkSplatShuffle(CI, Builder)) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h index e3dfc66d1b8..f550dd539fd 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -439,7 +439,7 @@ private: Instruction *scalarizePHI(ExtractElementInst &EI, PHINode *PN); Value *EvaluateInDifferentElementOrder(Value *V, ArrayRef<int> Mask); Instruction *foldCastedBitwiseLogic(BinaryOperator &I); - Instruction *shrinkBitwiseLogic(TruncInst &Trunc); + Instruction *narrowBinOp(TruncInst &Trunc); Instruction *optimizeBitCastFromPhi(CastInst &CI, PHINode *PN); /// Determine if a pair of casts can be replaced by a single cast. |