mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[InstCombine] break up visitICmpInstWithInstAndIntCst(); NFCI
Making smaller pieces out of some of these ~1000 line functions should make it easier to incrementally upgrade them to handle vector types. llvm-svn: 276304
This commit is contained in:
parent
6248146d05
commit
4385ad44ac
@ -2196,175 +2196,182 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
|
||||
break;
|
||||
}
|
||||
|
||||
// Simplify icmp_eq and icmp_ne instructions with integer constant RHS.
|
||||
if (ICI.isEquality()) {
|
||||
bool isICMP_NE = ICI.getPredicate() == ICmpInst::ICMP_NE;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If the first operand is (add|sub|and|or|xor|rem) with a constant, and
|
||||
// the second operand is a constant, simplify a bit.
|
||||
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(LHSI)) {
|
||||
switch (BO->getOpcode()) {
|
||||
case Instruction::SRem:
|
||||
// If we have a signed (X % (2^c)) == 0, turn it into an unsigned one.
|
||||
if (RHSV == 0 && isa<ConstantInt>(BO->getOperand(1)) &&BO->hasOneUse()){
|
||||
const APInt &V = cast<ConstantInt>(BO->getOperand(1))->getValue();
|
||||
if (V.sgt(1) && V.isPowerOf2()) {
|
||||
Value *NewRem =
|
||||
Builder->CreateURem(BO->getOperand(0), BO->getOperand(1),
|
||||
BO->getName());
|
||||
return new ICmpInst(ICI.getPredicate(), NewRem,
|
||||
Constant::getNullValue(BO->getType()));
|
||||
}
|
||||
/// Simplify icmp_eq and icmp_ne instructions with integer constant RHS.
|
||||
Instruction *InstCombiner::visitICmpEqualityWithConstant(ICmpInst &ICI,
|
||||
Instruction *LHSI,
|
||||
ConstantInt *RHS) {
|
||||
if (!ICI.isEquality())
|
||||
return nullptr;
|
||||
|
||||
const APInt &RHSV = RHS->getValue();
|
||||
bool isICMP_NE = ICI.getPredicate() == ICmpInst::ICMP_NE;
|
||||
|
||||
// If the first operand is (add|sub|and|or|xor|rem) with a constant, and
|
||||
// the second operand is a constant, simplify a bit.
|
||||
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(LHSI)) {
|
||||
switch (BO->getOpcode()) {
|
||||
case Instruction::SRem:
|
||||
// If we have a signed (X % (2^c)) == 0, turn it into an unsigned one.
|
||||
if (RHSV == 0 && isa<ConstantInt>(BO->getOperand(1)) && BO->hasOneUse()) {
|
||||
const APInt &V = cast<ConstantInt>(BO->getOperand(1))->getValue();
|
||||
if (V.sgt(1) && V.isPowerOf2()) {
|
||||
Value *NewRem = Builder->CreateURem(BO->getOperand(0),
|
||||
BO->getOperand(1), BO->getName());
|
||||
return new ICmpInst(ICI.getPredicate(), NewRem,
|
||||
Constant::getNullValue(BO->getType()));
|
||||
}
|
||||
break;
|
||||
case Instruction::Add:
|
||||
// Replace ((add A, B) != C) with (A != C-B) if B & C are constants.
|
||||
if (ConstantInt *BOp1C = dyn_cast<ConstantInt>(BO->getOperand(1))) {
|
||||
if (BO->hasOneUse())
|
||||
return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
|
||||
ConstantExpr::getSub(RHS, BOp1C));
|
||||
} else if (RHSV == 0) {
|
||||
// Replace ((add A, B) != 0) with (A != -B) if A or B is
|
||||
// efficiently invertible, or if the add has just this one use.
|
||||
Value *BOp0 = BO->getOperand(0), *BOp1 = BO->getOperand(1);
|
||||
|
||||
if (Value *NegVal = dyn_castNegVal(BOp1))
|
||||
return new ICmpInst(ICI.getPredicate(), BOp0, NegVal);
|
||||
if (Value *NegVal = dyn_castNegVal(BOp0))
|
||||
return new ICmpInst(ICI.getPredicate(), NegVal, BOp1);
|
||||
if (BO->hasOneUse()) {
|
||||
Value *Neg = Builder->CreateNeg(BOp1);
|
||||
Neg->takeName(BO);
|
||||
return new ICmpInst(ICI.getPredicate(), BOp0, Neg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Instruction::Xor:
|
||||
if (BO->hasOneUse()) {
|
||||
if (Constant *BOC = dyn_cast<Constant>(BO->getOperand(1))) {
|
||||
// For the xor case, we can xor two constants together, eliminating
|
||||
// the explicit xor.
|
||||
return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
|
||||
ConstantExpr::getXor(RHS, BOC));
|
||||
} else if (RHSV == 0) {
|
||||
// Replace ((xor A, B) != 0) with (A != B)
|
||||
return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
|
||||
BO->getOperand(1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Instruction::Sub:
|
||||
if (BO->hasOneUse()) {
|
||||
if (ConstantInt *BOp0C = dyn_cast<ConstantInt>(BO->getOperand(0))) {
|
||||
// Replace ((sub A, B) != C) with (B != A-C) if A & C are constants.
|
||||
return new ICmpInst(ICI.getPredicate(), BO->getOperand(1),
|
||||
ConstantExpr::getSub(BOp0C, RHS));
|
||||
} else if (RHSV == 0) {
|
||||
// Replace ((sub A, B) != 0) with (A != B)
|
||||
return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
|
||||
BO->getOperand(1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Instruction::Or:
|
||||
// If bits are being or'd in that are not present in the constant we
|
||||
// are comparing against, then the comparison could never succeed!
|
||||
if (ConstantInt *BOC = dyn_cast<ConstantInt>(BO->getOperand(1))) {
|
||||
Constant *NotCI = ConstantExpr::getNot(RHS);
|
||||
if (!ConstantExpr::getAnd(BOC, NotCI)->isNullValue())
|
||||
return replaceInstUsesWith(ICI, Builder->getInt1(isICMP_NE));
|
||||
|
||||
// Comparing if all bits outside of a constant mask are set?
|
||||
// Replace (X | C) == -1 with (X & ~C) == ~C.
|
||||
// This removes the -1 constant.
|
||||
if (BO->hasOneUse() && RHS->isAllOnesValue()) {
|
||||
Constant *NotBOC = ConstantExpr::getNot(BOC);
|
||||
Value *And = Builder->CreateAnd(BO->getOperand(0), NotBOC);
|
||||
return new ICmpInst(ICI.getPredicate(), And, NotBOC);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Instruction::And:
|
||||
if (ConstantInt *BOC = dyn_cast<ConstantInt>(BO->getOperand(1))) {
|
||||
// If bits are being compared against that are and'd out, then the
|
||||
// comparison can never succeed!
|
||||
if ((RHSV & ~BOC->getValue()) != 0)
|
||||
return replaceInstUsesWith(ICI, Builder->getInt1(isICMP_NE));
|
||||
|
||||
// If we have ((X & C) == C), turn it into ((X & C) != 0).
|
||||
if (RHS == BOC && RHSV.isPowerOf2())
|
||||
return new ICmpInst(isICMP_NE ? ICmpInst::ICMP_EQ :
|
||||
ICmpInst::ICMP_NE, LHSI,
|
||||
Constant::getNullValue(RHS->getType()));
|
||||
|
||||
// Don't perform the following transforms if the AND has multiple uses
|
||||
if (!BO->hasOneUse())
|
||||
break;
|
||||
|
||||
// Replace (and X, (1 << size(X)-1) != 0) with x s< 0
|
||||
if (BOC->getValue().isSignBit()) {
|
||||
Value *X = BO->getOperand(0);
|
||||
Constant *Zero = Constant::getNullValue(X->getType());
|
||||
ICmpInst::Predicate pred = isICMP_NE ?
|
||||
ICmpInst::ICMP_SLT : ICmpInst::ICMP_SGE;
|
||||
return new ICmpInst(pred, X, Zero);
|
||||
}
|
||||
|
||||
// ((X & ~7) == 0) --> X < 8
|
||||
if (RHSV == 0 && isHighOnes(BOC)) {
|
||||
Value *X = BO->getOperand(0);
|
||||
Constant *NegX = ConstantExpr::getNeg(BOC);
|
||||
ICmpInst::Predicate pred = isICMP_NE ?
|
||||
ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT;
|
||||
return new ICmpInst(pred, X, NegX);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Instruction::Mul:
|
||||
if (RHSV == 0 && BO->hasNoSignedWrap()) {
|
||||
if (ConstantInt *BOC = dyn_cast<ConstantInt>(BO->getOperand(1))) {
|
||||
// The trivial case (mul X, 0) is handled by InstSimplify
|
||||
// General case : (mul X, C) != 0 iff X != 0
|
||||
// (mul X, C) == 0 iff X == 0
|
||||
if (!BOC->isZero())
|
||||
return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
|
||||
Constant::getNullValue(RHS->getType()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
} else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(LHSI)) {
|
||||
// Handle icmp {eq|ne} <intrinsic>, intcst.
|
||||
switch (II->getIntrinsicID()) {
|
||||
case Intrinsic::bswap:
|
||||
break;
|
||||
case Instruction::Add:
|
||||
// Replace ((add A, B) != C) with (A != C-B) if B & C are constants.
|
||||
if (ConstantInt *BOp1C = dyn_cast<ConstantInt>(BO->getOperand(1))) {
|
||||
if (BO->hasOneUse())
|
||||
return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
|
||||
ConstantExpr::getSub(RHS, BOp1C));
|
||||
} else if (RHSV == 0) {
|
||||
// Replace ((add A, B) != 0) with (A != -B) if A or B is
|
||||
// efficiently invertible, or if the add has just this one use.
|
||||
Value *BOp0 = BO->getOperand(0), *BOp1 = BO->getOperand(1);
|
||||
|
||||
if (Value *NegVal = dyn_castNegVal(BOp1))
|
||||
return new ICmpInst(ICI.getPredicate(), BOp0, NegVal);
|
||||
if (Value *NegVal = dyn_castNegVal(BOp0))
|
||||
return new ICmpInst(ICI.getPredicate(), NegVal, BOp1);
|
||||
if (BO->hasOneUse()) {
|
||||
Value *Neg = Builder->CreateNeg(BOp1);
|
||||
Neg->takeName(BO);
|
||||
return new ICmpInst(ICI.getPredicate(), BOp0, Neg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Instruction::Xor:
|
||||
if (BO->hasOneUse()) {
|
||||
if (Constant *BOC = dyn_cast<Constant>(BO->getOperand(1))) {
|
||||
// For the xor case, we can xor two constants together, eliminating
|
||||
// the explicit xor.
|
||||
return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
|
||||
ConstantExpr::getXor(RHS, BOC));
|
||||
} else if (RHSV == 0) {
|
||||
// Replace ((xor A, B) != 0) with (A != B)
|
||||
return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
|
||||
BO->getOperand(1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Instruction::Sub:
|
||||
if (BO->hasOneUse()) {
|
||||
if (ConstantInt *BOp0C = dyn_cast<ConstantInt>(BO->getOperand(0))) {
|
||||
// Replace ((sub A, B) != C) with (B != A-C) if A & C are constants.
|
||||
return new ICmpInst(ICI.getPredicate(), BO->getOperand(1),
|
||||
ConstantExpr::getSub(BOp0C, RHS));
|
||||
} else if (RHSV == 0) {
|
||||
// Replace ((sub A, B) != 0) with (A != B)
|
||||
return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
|
||||
BO->getOperand(1));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Instruction::Or:
|
||||
// If bits are being or'd in that are not present in the constant we
|
||||
// are comparing against, then the comparison could never succeed!
|
||||
if (ConstantInt *BOC = dyn_cast<ConstantInt>(BO->getOperand(1))) {
|
||||
Constant *NotCI = ConstantExpr::getNot(RHS);
|
||||
if (!ConstantExpr::getAnd(BOC, NotCI)->isNullValue())
|
||||
return replaceInstUsesWith(ICI, Builder->getInt1(isICMP_NE));
|
||||
|
||||
// Comparing if all bits outside of a constant mask are set?
|
||||
// Replace (X | C) == -1 with (X & ~C) == ~C.
|
||||
// This removes the -1 constant.
|
||||
if (BO->hasOneUse() && RHS->isAllOnesValue()) {
|
||||
Constant *NotBOC = ConstantExpr::getNot(BOC);
|
||||
Value *And = Builder->CreateAnd(BO->getOperand(0), NotBOC);
|
||||
return new ICmpInst(ICI.getPredicate(), And, NotBOC);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Instruction::And:
|
||||
if (ConstantInt *BOC = dyn_cast<ConstantInt>(BO->getOperand(1))) {
|
||||
// If bits are being compared against that are and'd out, then the
|
||||
// comparison can never succeed!
|
||||
if ((RHSV & ~BOC->getValue()) != 0)
|
||||
return replaceInstUsesWith(ICI, Builder->getInt1(isICMP_NE));
|
||||
|
||||
// If we have ((X & C) == C), turn it into ((X & C) != 0).
|
||||
if (RHS == BOC && RHSV.isPowerOf2())
|
||||
return new ICmpInst(isICMP_NE ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE,
|
||||
LHSI, Constant::getNullValue(RHS->getType()));
|
||||
|
||||
// Don't perform the following transforms if the AND has multiple uses
|
||||
if (!BO->hasOneUse())
|
||||
break;
|
||||
|
||||
// Replace (and X, (1 << size(X)-1) != 0) with x s< 0
|
||||
if (BOC->getValue().isSignBit()) {
|
||||
Value *X = BO->getOperand(0);
|
||||
Constant *Zero = Constant::getNullValue(X->getType());
|
||||
ICmpInst::Predicate pred =
|
||||
isICMP_NE ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_SGE;
|
||||
return new ICmpInst(pred, X, Zero);
|
||||
}
|
||||
|
||||
// ((X & ~7) == 0) --> X < 8
|
||||
if (RHSV == 0 && isHighOnes(BOC)) {
|
||||
Value *X = BO->getOperand(0);
|
||||
Constant *NegX = ConstantExpr::getNeg(BOC);
|
||||
ICmpInst::Predicate pred =
|
||||
isICMP_NE ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT;
|
||||
return new ICmpInst(pred, X, NegX);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Instruction::Mul:
|
||||
if (RHSV == 0 && BO->hasNoSignedWrap()) {
|
||||
if (ConstantInt *BOC = dyn_cast<ConstantInt>(BO->getOperand(1))) {
|
||||
// The trivial case (mul X, 0) is handled by InstSimplify
|
||||
// General case : (mul X, C) != 0 iff X != 0
|
||||
// (mul X, C) == 0 iff X == 0
|
||||
if (!BOC->isZero())
|
||||
return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
|
||||
Constant::getNullValue(RHS->getType()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(LHSI)) {
|
||||
// Handle icmp {eq|ne} <intrinsic>, intcst.
|
||||
switch (II->getIntrinsicID()) {
|
||||
case Intrinsic::bswap:
|
||||
Worklist.Add(II);
|
||||
ICI.setOperand(0, II->getArgOperand(0));
|
||||
ICI.setOperand(1, Builder->getInt(RHSV.byteSwap()));
|
||||
return &ICI;
|
||||
case Intrinsic::ctlz:
|
||||
case Intrinsic::cttz:
|
||||
// ctz(A) == bitwidth(a) -> A == 0 and likewise for !=
|
||||
if (RHSV == RHS->getType()->getBitWidth()) {
|
||||
Worklist.Add(II);
|
||||
ICI.setOperand(0, II->getArgOperand(0));
|
||||
ICI.setOperand(1, Builder->getInt(RHSV.byteSwap()));
|
||||
ICI.setOperand(1, ConstantInt::get(RHS->getType(), 0));
|
||||
return &ICI;
|
||||
case Intrinsic::ctlz:
|
||||
case Intrinsic::cttz:
|
||||
// ctz(A) == bitwidth(a) -> A == 0 and likewise for !=
|
||||
if (RHSV == RHS->getType()->getBitWidth()) {
|
||||
Worklist.Add(II);
|
||||
ICI.setOperand(0, II->getArgOperand(0));
|
||||
ICI.setOperand(1, ConstantInt::get(RHS->getType(), 0));
|
||||
return &ICI;
|
||||
}
|
||||
break;
|
||||
case Intrinsic::ctpop:
|
||||
// popcount(A) == 0 -> A == 0 and likewise for !=
|
||||
if (RHS->isZero()) {
|
||||
Worklist.Add(II);
|
||||
ICI.setOperand(0, II->getArgOperand(0));
|
||||
ICI.setOperand(1, RHS);
|
||||
return &ICI;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Intrinsic::ctpop:
|
||||
// popcount(A) == 0 -> A == 0 and likewise for !=
|
||||
if (RHS->isZero()) {
|
||||
Worklist.Add(II);
|
||||
ICI.setOperand(0, II->getArgOperand(0));
|
||||
ICI.setOperand(1, RHS);
|
||||
return &ICI;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@ -3621,10 +3628,12 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
|
||||
// Since the RHS is a ConstantInt (CI), if the left hand side is an
|
||||
// instruction, see if that instruction also has constants so that the
|
||||
// instruction can be folded into the icmp
|
||||
if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
|
||||
if (Instruction *LHSI = dyn_cast<Instruction>(Op0)) {
|
||||
if (Instruction *Res = visitICmpInstWithInstAndIntCst(I, LHSI, CI))
|
||||
return Res;
|
||||
|
||||
if (Instruction *Res = visitICmpEqualityWithConstant(I, LHSI, CI))
|
||||
return Res;
|
||||
}
|
||||
// (icmp eq/ne (udiv A, B), 0) -> (icmp ugt/ule i32 B, A)
|
||||
if (I.isEquality() && CI->isZero() &&
|
||||
match(Op0, m_UDiv(m_Value(A), m_Value(B)))) {
|
||||
|
@ -272,6 +272,8 @@ public:
|
||||
Instruction *visitICmpInstWithCastAndCast(ICmpInst &ICI);
|
||||
Instruction *visitICmpInstWithInstAndIntCst(ICmpInst &ICI, Instruction *LHS,
|
||||
ConstantInt *RHS);
|
||||
Instruction *visitICmpEqualityWithConstant(ICmpInst &ICI, Instruction *LHS,
|
||||
ConstantInt *RHS);
|
||||
Instruction *FoldICmpDivCst(ICmpInst &ICI, BinaryOperator *DivI,
|
||||
ConstantInt *DivRHS);
|
||||
Instruction *FoldICmpShrCst(ICmpInst &ICI, BinaryOperator *DivI,
|
||||
|
Loading…
Reference in New Issue
Block a user