[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
This commit is contained in:
Sanjay Patel 2017-08-05 15:19:18 +00:00
parent d51a35e339
commit 94da1de1ce
2 changed files with 38 additions and 40 deletions

View File

@ -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))

View File

@ -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.