Changeset View
Changeset View
Standalone View
Standalone View
lib/Transforms/InstCombine/InstCombineAddSub.cpp
Show First 20 Lines • Show All 1,061 Lines • ▼ Show 20 Lines | Instruction *InstCombiner::visitAdd(BinaryOperator &I) { | ||||
// FIXME: Use the match above instead of dyn_cast to allow these transforms | // FIXME: Use the match above instead of dyn_cast to allow these transforms | ||||
// for splat vectors. | // for splat vectors. | ||||
if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) { | if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) { | ||||
// See if SimplifyDemandedBits can simplify this. This handles stuff like | // See if SimplifyDemandedBits can simplify this. This handles stuff like | ||||
// (X & 254)+1 -> (X&254)|1 | // (X & 254)+1 -> (X&254)|1 | ||||
if (SimplifyDemandedInstructionBits(I)) | if (SimplifyDemandedInstructionBits(I)) | ||||
return &I; | return &I; | ||||
// zext(bool) + C -> bool ? C + 1 : C | // add (zext (icmp Pred X, Y)), -1 --> sext (icmp Pred' X, Y) | ||||
efriedma: I guess we should prefer sext(cmp) over add(zext(cmp), -1), but we prefer add(zext(cmp), N)… | |||||
if (ZExtInst *ZI = dyn_cast<ZExtInst>(LHS)) | Instruction *ZextOp; | ||||
if (ZI->getSrcTy()->isIntegerTy(1)) | ICmpInst::Predicate Pred; | ||||
return SelectInst::Create(ZI->getOperand(0), AddOne(CI), CI); | Value *X, *Y; | ||||
if (CI->getSExtValue() == -1 && match(LHS, m_ZExt(m_Instruction(ZextOp))) && | |||||
match(ZextOp, m_OneUse(m_ICmp(Pred, m_Value(X), m_Value(Y))))) { | |||||
// We have this pattern: if the compare is true, return 0; | |||||
// if the compare is false, return -1. | |||||
// Transform it to: if the inverse compare is true, return -1; | |||||
// if the inverse compare is false, return 0. | |||||
auto *Cmp = Builder->CreateICmp(CmpInst::getInversePredicate(Pred), X, Y); | |||||
return CastInst::Create(Instruction::SExt, Cmp, I.getType()); | |||||
} | |||||
Value *XorLHS = nullptr; ConstantInt *XorRHS = nullptr; | Value *XorLHS = nullptr; ConstantInt *XorRHS = nullptr; | ||||
if (match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) { | if (match(LHS, m_Xor(m_Value(XorLHS), m_ConstantInt(XorRHS)))) { | ||||
uint32_t TySizeBits = I.getType()->getScalarSizeInBits(); | uint32_t TySizeBits = I.getType()->getScalarSizeInBits(); | ||||
const APInt &RHSVal = CI->getValue(); | const APInt &RHSVal = CI->getValue(); | ||||
unsigned ExtendAmt = 0; | unsigned ExtendAmt = 0; | ||||
// If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext. | // If we have ADD(XOR(AND(X, 0xFF), 0x80), 0xF..F80), it's a sext. | ||||
// If we have ADD(XOR(AND(X, 0xFF), 0xF..F80), 0x80), it's a sext. | // If we have ADD(XOR(AND(X, 0xFF), 0xF..F80), 0x80), it's a sext. | ||||
▲ Show 20 Lines • Show All 659 Lines • Show Last 20 Lines |
I guess we should prefer sext(cmp) over add(zext(cmp), -1), but we prefer add(zext(cmp), N) over add(sext(cmp), N-1) for any other N? That works, but you might want to explain that here.