forked from OSchip/llvm-project
[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:
parent
d51a35e339
commit
94da1de1ce
|
@ -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))
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue