[InstCombine, InstSimplify] Move xforms from Combine to Simplify

There were several SelectInst combines that always returned an existing
instruction instead of modifying an old one or creating a new one.
These are prime candidates for moving to InstSimplify.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239229 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Majnemer 2015-06-06 22:40:21 +00:00
parent ce986b6bc0
commit 134cb22902
2 changed files with 140 additions and 126 deletions

View File

@ -3144,6 +3144,90 @@ Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
RecursionLimit); RecursionLimit);
} }
/// SimplifyWithOpReplaced - See if V simplifies when its operand Op is
/// replaced with RepOp.
static const Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
const Query &Q,
unsigned MaxRecurse) {
// Trivial replacement.
if (V == Op)
return RepOp;
auto *I = dyn_cast<Instruction>(V);
if (!I)
return nullptr;
// If this is a binary operator, try to simplify it with the replaced op.
if (auto *B = dyn_cast<BinaryOperator>(I)) {
// Consider:
// %cmp = icmp eq i32 %x, 2147483647
// %add = add nsw i32 %x, 1
// %sel = select i1 %cmp, i32 -2147483648, i32 %add
//
// We can't replace %sel with %add unless we strip away the flags.
if (isa<OverflowingBinaryOperator>(B))
if (B->hasNoSignedWrap() || B->hasNoUnsignedWrap())
return nullptr;
if (isa<PossiblyExactOperator>(B))
if (B->isExact())
return nullptr;
if (MaxRecurse) {
if (B->getOperand(0) == Op)
return SimplifyBinOp(B->getOpcode(), RepOp, B->getOperand(1), Q,
MaxRecurse - 1);
if (B->getOperand(1) == Op)
return SimplifyBinOp(B->getOpcode(), B->getOperand(0), RepOp, Q,
MaxRecurse - 1);
}
}
// Same for CmpInsts.
if (CmpInst *C = dyn_cast<CmpInst>(I)) {
if (MaxRecurse) {
if (C->getOperand(0) == Op)
return SimplifyCmpInst(C->getPredicate(), RepOp, C->getOperand(1), Q,
MaxRecurse - 1);
if (C->getOperand(1) == Op)
return SimplifyCmpInst(C->getPredicate(), C->getOperand(0), RepOp, Q,
MaxRecurse - 1);
}
}
// TODO: We could hand off more cases to instsimplify here.
// If all operands are constant after substituting Op for RepOp then we can
// constant fold the instruction.
if (Constant *CRepOp = dyn_cast<Constant>(RepOp)) {
// Build a list of all constant operands.
SmallVector<Constant *, 8> ConstOps;
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
if (I->getOperand(i) == Op)
ConstOps.push_back(CRepOp);
else if (Constant *COp = dyn_cast<Constant>(I->getOperand(i)))
ConstOps.push_back(COp);
else
break;
}
// All operands were constants, fold it.
if (ConstOps.size() == I->getNumOperands()) {
if (CmpInst *C = dyn_cast<CmpInst>(I))
return ConstantFoldCompareInstOperands(C->getPredicate(), ConstOps[0],
ConstOps[1], Q.DL, Q.TLI);
if (LoadInst *LI = dyn_cast<LoadInst>(I))
if (!LI->isVolatile())
return ConstantFoldLoadFromConstPtr(ConstOps[0], Q.DL);
return ConstantFoldInstOperands(I->getOpcode(), I->getType(), ConstOps,
Q.DL, Q.TLI);
}
}
return nullptr;
}
/// SimplifySelectInst - Given operands for a SelectInst, see if we can fold /// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
/// the result. If not, this returns null. /// the result. If not, this returns null.
static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal, static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal,
@ -3172,29 +3256,28 @@ static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal,
if (isa<UndefValue>(FalseVal)) // select C, X, undef -> X if (isa<UndefValue>(FalseVal)) // select C, X, undef -> X
return TrueVal; return TrueVal;
const auto *ICI = dyn_cast<ICmpInst>(CondVal); if (const auto *ICI = dyn_cast<ICmpInst>(CondVal)) {
unsigned BitWidth = TrueVal->getType()->getScalarSizeInBits(); unsigned BitWidth = Q.DL.getTypeSizeInBits(TrueVal->getType());
if (ICI && BitWidth) {
ICmpInst::Predicate Pred = ICI->getPredicate(); ICmpInst::Predicate Pred = ICI->getPredicate();
Value *CmpLHS = ICI->getOperand(0);
Value *CmpRHS = ICI->getOperand(1);
APInt MinSignedValue = APInt::getSignBit(BitWidth); APInt MinSignedValue = APInt::getSignBit(BitWidth);
Value *X; Value *X;
const APInt *Y; const APInt *Y;
bool TrueWhenUnset; bool TrueWhenUnset;
bool IsBitTest = false; bool IsBitTest = false;
if (ICmpInst::isEquality(Pred) && if (ICmpInst::isEquality(Pred) &&
match(ICI->getOperand(0), m_And(m_Value(X), m_APInt(Y))) && match(CmpLHS, m_And(m_Value(X), m_APInt(Y))) &&
match(ICI->getOperand(1), m_Zero())) { match(CmpRHS, m_Zero())) {
IsBitTest = true; IsBitTest = true;
TrueWhenUnset = Pred == ICmpInst::ICMP_EQ; TrueWhenUnset = Pred == ICmpInst::ICMP_EQ;
} else if (Pred == ICmpInst::ICMP_SLT && } else if (Pred == ICmpInst::ICMP_SLT && match(CmpRHS, m_Zero())) {
match(ICI->getOperand(1), m_Zero())) { X = CmpLHS;
X = ICI->getOperand(0);
Y = &MinSignedValue; Y = &MinSignedValue;
IsBitTest = true; IsBitTest = true;
TrueWhenUnset = false; TrueWhenUnset = false;
} else if (Pred == ICmpInst::ICMP_SGT && } else if (Pred == ICmpInst::ICMP_SGT && match(CmpRHS, m_AllOnes())) {
match(ICI->getOperand(1), m_AllOnes())) { X = CmpLHS;
X = ICI->getOperand(0);
Y = &MinSignedValue; Y = &MinSignedValue;
IsBitTest = true; IsBitTest = true;
TrueWhenUnset = true; TrueWhenUnset = true;
@ -3225,6 +3308,50 @@ static Value *SimplifySelectInst(Value *CondVal, Value *TrueVal,
return TrueWhenUnset ? TrueVal : FalseVal; return TrueWhenUnset ? TrueVal : FalseVal;
} }
} }
if (ICI->hasOneUse()) {
const APInt *C;
if (match(CmpRHS, m_APInt(C))) {
// X < MIN ? T : F --> F
if (Pred == ICmpInst::ICMP_SLT && C->isMinSignedValue())
return FalseVal;
// X < MIN ? T : F --> F
if (Pred == ICmpInst::ICMP_ULT && C->isMinValue())
return FalseVal;
// X > MAX ? T : F --> F
if (Pred == ICmpInst::ICMP_SGT && C->isMaxSignedValue())
return FalseVal;
// X > MAX ? T : F --> F
if (Pred == ICmpInst::ICMP_UGT && C->isMaxValue())
return FalseVal;
}
}
// If we have an equality comparison then we know the value in one of the
// arms of the select. See if substituting this value into the arm and
// simplifying the result yields the same value as the other arm.
if (Pred == ICmpInst::ICMP_EQ) {
if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, Q, MaxRecurse) ==
TrueVal ||
SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, Q, MaxRecurse) ==
TrueVal)
return FalseVal;
if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, Q, MaxRecurse) ==
FalseVal ||
SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, Q, MaxRecurse) ==
FalseVal)
return FalseVal;
} else if (Pred == ICmpInst::ICMP_NE) {
if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, Q, MaxRecurse) ==
FalseVal ||
SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, Q, MaxRecurse) ==
FalseVal)
return TrueVal;
if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, Q, MaxRecurse) ==
TrueVal ||
SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, Q, MaxRecurse) ==
TrueVal)
return TrueVal;
}
} }
return nullptr; return nullptr;

View File

@ -276,85 +276,6 @@ Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value *TrueVal,
return nullptr; return nullptr;
} }
/// SimplifyWithOpReplaced - See if V simplifies when its operand Op is
/// replaced with RepOp.
static Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
const TargetLibraryInfo *TLI,
const DataLayout &DL, DominatorTree *DT,
AssumptionCache *AC) {
// Trivial replacement.
if (V == Op)
return RepOp;
Instruction *I = dyn_cast<Instruction>(V);
if (!I)
return nullptr;
// If this is a binary operator, try to simplify it with the replaced op.
if (BinaryOperator *B = dyn_cast<BinaryOperator>(I)) {
// Consider:
// %cmp = icmp eq i32 %x, 2147483647
// %add = add nsw i32 %x, 1
// %sel = select i1 %cmp, i32 -2147483648, i32 %add
//
// We can't replace %sel with %add unless we strip away the flags.
if (isa<OverflowingBinaryOperator>(B))
if (B->hasNoSignedWrap() || B->hasNoUnsignedWrap())
return nullptr;
if (isa<PossiblyExactOperator>(B))
if (B->isExact())
return nullptr;
if (B->getOperand(0) == Op)
return SimplifyBinOp(B->getOpcode(), RepOp, B->getOperand(1), DL, TLI);
if (B->getOperand(1) == Op)
return SimplifyBinOp(B->getOpcode(), B->getOperand(0), RepOp, DL, TLI);
}
// Same for CmpInsts.
if (CmpInst *C = dyn_cast<CmpInst>(I)) {
if (C->getOperand(0) == Op)
return SimplifyCmpInst(C->getPredicate(), RepOp, C->getOperand(1), DL,
TLI, DT, AC);
if (C->getOperand(1) == Op)
return SimplifyCmpInst(C->getPredicate(), C->getOperand(0), RepOp, DL,
TLI, DT, AC);
}
// TODO: We could hand off more cases to instsimplify here.
// If all operands are constant after substituting Op for RepOp then we can
// constant fold the instruction.
if (Constant *CRepOp = dyn_cast<Constant>(RepOp)) {
// Build a list of all constant operands.
SmallVector<Constant*, 8> ConstOps;
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
if (I->getOperand(i) == Op)
ConstOps.push_back(CRepOp);
else if (Constant *COp = dyn_cast<Constant>(I->getOperand(i)))
ConstOps.push_back(COp);
else
break;
}
// All operands were constants, fold it.
if (ConstOps.size() == I->getNumOperands()) {
if (CmpInst *C = dyn_cast<CmpInst>(I))
return ConstantFoldCompareInstOperands(C->getPredicate(), ConstOps[0],
ConstOps[1], DL, TLI);
if (LoadInst *LI = dyn_cast<LoadInst>(I))
if (!LI->isVolatile())
return ConstantFoldLoadFromConstPtr(ConstOps[0], DL);
return ConstantFoldInstOperands(I->getOpcode(), I->getType(), ConstOps,
DL, TLI);
}
}
return nullptr;
}
/// foldSelectICmpAndOr - We want to turn: /// foldSelectICmpAndOr - We want to turn:
/// (select (icmp eq (and X, C1), 0), Y, (or Y, C2)) /// (select (icmp eq (and X, C1), 0), Y, (or Y, C2))
/// into: /// into:
@ -490,14 +411,6 @@ Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI,
// here, so make sure the select is the only user. // here, so make sure the select is the only user.
if (ICI->hasOneUse()) if (ICI->hasOneUse())
if (ConstantInt *CI = dyn_cast<ConstantInt>(CmpRHS)) { if (ConstantInt *CI = dyn_cast<ConstantInt>(CmpRHS)) {
// X < MIN ? T : F --> F
if ((Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_ULT)
&& CI->isMinValue(Pred == ICmpInst::ICMP_SLT))
return ReplaceInstUsesWith(SI, FalseVal);
// X > MAX ? T : F --> F
else if ((Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_UGT)
&& CI->isMaxValue(Pred == ICmpInst::ICMP_SGT))
return ReplaceInstUsesWith(SI, FalseVal);
switch (Pred) { switch (Pred) {
default: break; default: break;
case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULT:
@ -611,33 +524,6 @@ Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI,
} }
} }
// If we have an equality comparison then we know the value in one of the
// arms of the select. See if substituting this value into the arm and
// simplifying the result yields the same value as the other arm.
if (Pred == ICmpInst::ICMP_EQ) {
if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, TLI, DL, DT, AC) ==
TrueVal ||
SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, TLI, DL, DT, AC) ==
TrueVal)
return ReplaceInstUsesWith(SI, FalseVal);
if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, TLI, DL, DT, AC) ==
FalseVal ||
SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, TLI, DL, DT, AC) ==
FalseVal)
return ReplaceInstUsesWith(SI, FalseVal);
} else if (Pred == ICmpInst::ICMP_NE) {
if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, TLI, DL, DT, AC) ==
FalseVal ||
SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, TLI, DL, DT, AC) ==
FalseVal)
return ReplaceInstUsesWith(SI, TrueVal);
if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, TLI, DL, DT, AC) ==
TrueVal ||
SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, TLI, DL, DT, AC) ==
TrueVal)
return ReplaceInstUsesWith(SI, TrueVal);
}
// NOTE: if we wanted to, this is where to detect integer MIN/MAX // NOTE: if we wanted to, this is where to detect integer MIN/MAX
if (CmpRHS != CmpLHS && isa<Constant>(CmpRHS)) { if (CmpRHS != CmpLHS && isa<Constant>(CmpRHS)) {
@ -652,7 +538,8 @@ Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI,
} }
} }
if (unsigned BitWidth = TrueVal->getType()->getScalarSizeInBits()) { {
unsigned BitWidth = DL.getTypeSizeInBits(TrueVal->getType());
APInt MinSignedValue = APInt::getSignBit(BitWidth); APInt MinSignedValue = APInt::getSignBit(BitWidth);
Value *X; Value *X;
const APInt *Y, *C; const APInt *Y, *C;