mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-03 18:29:08 +00:00
inline the FoldICmpLogical functor.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92695 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
54de3ea1ca
commit
a317e044fb
@ -1254,33 +1254,33 @@ static unsigned getFCmpCode(FCmpInst::Predicate CC, bool &isOrdered) {
|
|||||||
/// opcode and two operands into either a constant true or false, or a brand
|
/// opcode and two operands into either a constant true or false, or a brand
|
||||||
/// new ICmp instruction. The sign is passed in to determine which kind
|
/// new ICmp instruction. The sign is passed in to determine which kind
|
||||||
/// of predicate to use in the new icmp instruction.
|
/// of predicate to use in the new icmp instruction.
|
||||||
static Value *getICmpValue(bool sign, unsigned code, Value *LHS, Value *RHS) {
|
static Value *getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS) {
|
||||||
switch (code) {
|
switch (Code) {
|
||||||
default: llvm_unreachable("Illegal ICmp code!");
|
default: assert(0 && "Illegal ICmp code!");
|
||||||
case 0: return ConstantInt::getFalse(LHS->getContext());
|
case 0:
|
||||||
case 1:
|
return ConstantInt::getFalse(LHS->getContext());
|
||||||
if (sign)
|
case 1:
|
||||||
|
if (Sign)
|
||||||
return new ICmpInst(ICmpInst::ICMP_SGT, LHS, RHS);
|
return new ICmpInst(ICmpInst::ICMP_SGT, LHS, RHS);
|
||||||
else
|
return new ICmpInst(ICmpInst::ICMP_UGT, LHS, RHS);
|
||||||
return new ICmpInst(ICmpInst::ICMP_UGT, LHS, RHS);
|
case 2:
|
||||||
case 2: return new ICmpInst(ICmpInst::ICMP_EQ, LHS, RHS);
|
return new ICmpInst(ICmpInst::ICMP_EQ, LHS, RHS);
|
||||||
case 3:
|
case 3:
|
||||||
if (sign)
|
if (Sign)
|
||||||
return new ICmpInst(ICmpInst::ICMP_SGE, LHS, RHS);
|
return new ICmpInst(ICmpInst::ICMP_SGE, LHS, RHS);
|
||||||
else
|
return new ICmpInst(ICmpInst::ICMP_UGE, LHS, RHS);
|
||||||
return new ICmpInst(ICmpInst::ICMP_UGE, LHS, RHS);
|
case 4:
|
||||||
case 4:
|
if (Sign)
|
||||||
if (sign)
|
|
||||||
return new ICmpInst(ICmpInst::ICMP_SLT, LHS, RHS);
|
return new ICmpInst(ICmpInst::ICMP_SLT, LHS, RHS);
|
||||||
else
|
return new ICmpInst(ICmpInst::ICMP_ULT, LHS, RHS);
|
||||||
return new ICmpInst(ICmpInst::ICMP_ULT, LHS, RHS);
|
case 5:
|
||||||
case 5: return new ICmpInst(ICmpInst::ICMP_NE, LHS, RHS);
|
return new ICmpInst(ICmpInst::ICMP_NE, LHS, RHS);
|
||||||
case 6:
|
case 6:
|
||||||
if (sign)
|
if (Sign)
|
||||||
return new ICmpInst(ICmpInst::ICMP_SLE, LHS, RHS);
|
return new ICmpInst(ICmpInst::ICMP_SLE, LHS, RHS);
|
||||||
else
|
return new ICmpInst(ICmpInst::ICMP_ULE, LHS, RHS);
|
||||||
return new ICmpInst(ICmpInst::ICMP_ULE, LHS, RHS);
|
case 7:
|
||||||
case 7: return ConstantInt::getTrue(LHS->getContext());
|
return ConstantInt::getTrue(LHS->getContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1338,50 +1338,6 @@ static bool PredicatesFoldable(ICmpInst::Predicate p1, ICmpInst::Predicate p2) {
|
|||||||
(CmpInst::isSigned(p2) && ICmpInst::isEquality(p1));
|
(CmpInst::isSigned(p2) && ICmpInst::isEquality(p1));
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
// FoldICmpLogical - Implements (icmp1 A, B) & (icmp2 A, B) --> (icmp3 A, B)
|
|
||||||
struct FoldICmpLogical {
|
|
||||||
InstCombiner ⁣
|
|
||||||
Value *LHS, *RHS;
|
|
||||||
ICmpInst::Predicate pred;
|
|
||||||
FoldICmpLogical(InstCombiner &ic, ICmpInst *ICI)
|
|
||||||
: IC(ic), LHS(ICI->getOperand(0)), RHS(ICI->getOperand(1)),
|
|
||||||
pred(ICI->getPredicate()) {}
|
|
||||||
bool shouldApply(Value *V) const {
|
|
||||||
if (ICmpInst *ICI = dyn_cast<ICmpInst>(V))
|
|
||||||
if (PredicatesFoldable(pred, ICI->getPredicate()))
|
|
||||||
return ((ICI->getOperand(0) == LHS && ICI->getOperand(1) == RHS) ||
|
|
||||||
(ICI->getOperand(0) == RHS && ICI->getOperand(1) == LHS));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Instruction *apply(Instruction &Log) const {
|
|
||||||
ICmpInst *ICI = cast<ICmpInst>(Log.getOperand(0));
|
|
||||||
if (ICI->getOperand(0) != LHS) {
|
|
||||||
assert(ICI->getOperand(1) == LHS);
|
|
||||||
ICI->swapOperands(); // Swap the LHS and RHS of the ICmp
|
|
||||||
}
|
|
||||||
|
|
||||||
ICmpInst *RHSICI = cast<ICmpInst>(Log.getOperand(1));
|
|
||||||
unsigned LHSCode = getICmpCode(ICI);
|
|
||||||
unsigned RHSCode = getICmpCode(RHSICI);
|
|
||||||
unsigned Code;
|
|
||||||
switch (Log.getOpcode()) {
|
|
||||||
case Instruction::And: Code = LHSCode & RHSCode; break;
|
|
||||||
case Instruction::Or: Code = LHSCode | RHSCode; break;
|
|
||||||
case Instruction::Xor: Code = LHSCode ^ RHSCode; break;
|
|
||||||
default: llvm_unreachable("Illegal logical opcode!"); return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isSigned = RHSICI->isSigned() || ICI->isSigned();
|
|
||||||
Value *RV = getICmpValue(isSigned, Code, LHS, RHS);
|
|
||||||
if (Instruction *I = dyn_cast<Instruction>(RV))
|
|
||||||
return I;
|
|
||||||
// Otherwise, it's a constant boolean value...
|
|
||||||
return IC.ReplaceInstUsesWith(Log, RV);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // end anonymous namespace
|
|
||||||
|
|
||||||
// OptAndOp - This handles expressions of the form ((val OP C1) & C2). Where
|
// OptAndOp - This handles expressions of the form ((val OP C1) & C2). Where
|
||||||
// the Op parameter is 'OP', OpRHS is 'C1', and AndRHS is 'C2'. Op is
|
// the Op parameter is 'OP', OpRHS is 'C1', and AndRHS is 'C2'. Op is
|
||||||
// guaranteed to be a binary operator.
|
// guaranteed to be a binary operator.
|
||||||
@ -1635,16 +1591,31 @@ Value *InstCombiner::FoldLogicalPlusAnd(Value *LHS, Value *RHS,
|
|||||||
/// FoldAndOfICmps - Fold (icmp)&(icmp) if possible.
|
/// FoldAndOfICmps - Fold (icmp)&(icmp) if possible.
|
||||||
Instruction *InstCombiner::FoldAndOfICmps(Instruction &I,
|
Instruction *InstCombiner::FoldAndOfICmps(Instruction &I,
|
||||||
ICmpInst *LHS, ICmpInst *RHS) {
|
ICmpInst *LHS, ICmpInst *RHS) {
|
||||||
Value *Val, *Val2;
|
ICmpInst::Predicate LHSCC = LHS->getPredicate(), RHSCC = RHS->getPredicate();
|
||||||
ConstantInt *LHSCst, *RHSCst;
|
|
||||||
ICmpInst::Predicate LHSCC, RHSCC;
|
// (icmp1 A, B) & (icmp2 A, B) --> (icmp3 A, B)
|
||||||
|
if (PredicatesFoldable(LHSCC, RHSCC)) {
|
||||||
|
if (LHS->getOperand(0) == RHS->getOperand(1) &&
|
||||||
|
LHS->getOperand(1) == RHS->getOperand(0))
|
||||||
|
LHS->swapOperands();
|
||||||
|
if (LHS->getOperand(0) == RHS->getOperand(0) &&
|
||||||
|
LHS->getOperand(1) == RHS->getOperand(1)) {
|
||||||
|
Value *Op0 = LHS->getOperand(0), *Op1 = LHS->getOperand(1);
|
||||||
|
unsigned Code = getICmpCode(LHS) & getICmpCode(RHS);
|
||||||
|
bool isSigned = LHS->isSigned() || RHS->isSigned();
|
||||||
|
Value *RV = getICmpValue(isSigned, Code, Op0, Op1);
|
||||||
|
if (Instruction *I = dyn_cast<Instruction>(RV))
|
||||||
|
return I;
|
||||||
|
// Otherwise, it's a constant boolean value.
|
||||||
|
return ReplaceInstUsesWith(I, RV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This only handles icmp of constants: (icmp1 A, C1) & (icmp2 B, C2).
|
// This only handles icmp of constants: (icmp1 A, C1) & (icmp2 B, C2).
|
||||||
if (!match(LHS, m_ICmp(LHSCC, m_Value(Val),
|
Value *Val = LHS->getOperand(0), *Val2 = RHS->getOperand(0);
|
||||||
m_ConstantInt(LHSCst))) ||
|
ConstantInt *LHSCst = dyn_cast<ConstantInt>(LHS->getOperand(1));
|
||||||
!match(RHS, m_ICmp(RHSCC, m_Value(Val2),
|
ConstantInt *RHSCst = dyn_cast<ConstantInt>(RHS->getOperand(1));
|
||||||
m_ConstantInt(RHSCst))))
|
if (LHSCst == 0 || RHSCst == 0) return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (LHSCst == RHSCst && LHSCC == RHSCC) {
|
if (LHSCst == RHSCst && LHSCC == RHSCC) {
|
||||||
// (icmp ult A, C) & (icmp ult B, C) --> (icmp ult (A|B), C)
|
// (icmp ult A, C) & (icmp ult B, C) --> (icmp ult (A|B), C)
|
||||||
@ -1696,7 +1667,7 @@ Instruction *InstCombiner::FoldAndOfICmps(Instruction &I,
|
|||||||
// comparing a value against two constants and and'ing the result
|
// comparing a value against two constants and and'ing the result
|
||||||
// together. Because of the above check, we know that we only have
|
// together. Because of the above check, we know that we only have
|
||||||
// icmp eq, icmp ne, icmp [su]lt, and icmp [SU]gt here. We also know
|
// icmp eq, icmp ne, icmp [su]lt, and icmp [SU]gt here. We also know
|
||||||
// (from the FoldICmpLogical check above), that the two constants
|
// (from the icmp folding check above), that the two constants
|
||||||
// are not equal and that the larger constant is on the RHS
|
// are not equal and that the larger constant is on the RHS
|
||||||
assert(LHSCst != RHSCst && "Compares not folded above?");
|
assert(LHSCst != RHSCst && "Compares not folded above?");
|
||||||
|
|
||||||
@ -2074,15 +2045,10 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
|||||||
return BinaryOperator::CreateAnd(A, Op0);
|
return BinaryOperator::CreateAnd(A, Op0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ICmpInst *RHS = dyn_cast<ICmpInst>(Op1)) {
|
if (ICmpInst *RHS = dyn_cast<ICmpInst>(Op1))
|
||||||
// (icmp1 A, B) & (icmp2 A, B) --> (icmp3 A, B)
|
|
||||||
if (Instruction *R = AssociativeOpt(I, FoldICmpLogical(*this, RHS)))
|
|
||||||
return R;
|
|
||||||
|
|
||||||
if (ICmpInst *LHS = dyn_cast<ICmpInst>(Op0))
|
if (ICmpInst *LHS = dyn_cast<ICmpInst>(Op0))
|
||||||
if (Instruction *Res = FoldAndOfICmps(I, LHS, RHS))
|
if (Instruction *Res = FoldAndOfICmps(I, LHS, RHS))
|
||||||
return Res;
|
return Res;
|
||||||
}
|
|
||||||
|
|
||||||
// fold (and (cast A), (cast B)) -> (cast (and A, B))
|
// fold (and (cast A), (cast B)) -> (cast (and A, B))
|
||||||
if (CastInst *Op0C = dyn_cast<CastInst>(Op0))
|
if (CastInst *Op0C = dyn_cast<CastInst>(Op0))
|
||||||
@ -2312,16 +2278,32 @@ static Instruction *MatchSelectFromAndOr(Value *A, Value *B,
|
|||||||
/// FoldOrOfICmps - Fold (icmp)|(icmp) if possible.
|
/// FoldOrOfICmps - Fold (icmp)|(icmp) if possible.
|
||||||
Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
|
Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
|
||||||
ICmpInst *LHS, ICmpInst *RHS) {
|
ICmpInst *LHS, ICmpInst *RHS) {
|
||||||
Value *Val, *Val2;
|
ICmpInst::Predicate LHSCC = LHS->getPredicate(), RHSCC = RHS->getPredicate();
|
||||||
ConstantInt *LHSCst, *RHSCst;
|
|
||||||
ICmpInst::Predicate LHSCC, RHSCC;
|
// (icmp1 A, B) | (icmp2 A, B) --> (icmp3 A, B)
|
||||||
|
if (PredicatesFoldable(LHSCC, RHSCC)) {
|
||||||
|
if (LHS->getOperand(0) == RHS->getOperand(1) &&
|
||||||
|
LHS->getOperand(1) == RHS->getOperand(0))
|
||||||
|
LHS->swapOperands();
|
||||||
|
if (LHS->getOperand(0) == RHS->getOperand(0) &&
|
||||||
|
LHS->getOperand(1) == RHS->getOperand(1)) {
|
||||||
|
Value *Op0 = LHS->getOperand(0), *Op1 = LHS->getOperand(1);
|
||||||
|
unsigned Code = getICmpCode(LHS) | getICmpCode(RHS);
|
||||||
|
bool isSigned = LHS->isSigned() || RHS->isSigned();
|
||||||
|
Value *RV = getICmpValue(isSigned, Code, Op0, Op1);
|
||||||
|
if (Instruction *I = dyn_cast<Instruction>(RV))
|
||||||
|
return I;
|
||||||
|
// Otherwise, it's a constant boolean value.
|
||||||
|
return ReplaceInstUsesWith(I, RV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This only handles icmp of constants: (icmp1 A, C1) | (icmp2 B, C2).
|
// This only handles icmp of constants: (icmp1 A, C1) | (icmp2 B, C2).
|
||||||
if (!match(LHS, m_ICmp(LHSCC, m_Value(Val), m_ConstantInt(LHSCst))) ||
|
Value *Val = LHS->getOperand(0), *Val2 = RHS->getOperand(0);
|
||||||
!match(RHS, m_ICmp(RHSCC, m_Value(Val2), m_ConstantInt(RHSCst))))
|
ConstantInt *LHSCst = dyn_cast<ConstantInt>(LHS->getOperand(1));
|
||||||
return 0;
|
ConstantInt *RHSCst = dyn_cast<ConstantInt>(RHS->getOperand(1));
|
||||||
|
if (LHSCst == 0 || RHSCst == 0) return 0;
|
||||||
|
|
||||||
|
|
||||||
// (icmp ne A, 0) | (icmp ne B, 0) --> (icmp ne (A|B), 0)
|
// (icmp ne A, 0) | (icmp ne B, 0) --> (icmp ne (A|B), 0)
|
||||||
if (LHSCst == RHSCst && LHSCC == RHSCC &&
|
if (LHSCst == RHSCst && LHSCC == RHSCC &&
|
||||||
LHSCC == ICmpInst::ICMP_NE && LHSCst->isZero()) {
|
LHSCC == ICmpInst::ICMP_NE && LHSCst->isZero()) {
|
||||||
@ -2363,7 +2345,7 @@ Instruction *InstCombiner::FoldOrOfICmps(Instruction &I,
|
|||||||
// comparing a value against two constants and or'ing the result
|
// comparing a value against two constants and or'ing the result
|
||||||
// together. Because of the above check, we know that we only have
|
// together. Because of the above check, we know that we only have
|
||||||
// ICMP_EQ, ICMP_NE, ICMP_LT, and ICMP_GT here. We also know (from the
|
// ICMP_EQ, ICMP_NE, ICMP_LT, and ICMP_GT here. We also know (from the
|
||||||
// FoldICmpLogical check above), that the two constants are not
|
// icmp folding check above), that the two constants are not
|
||||||
// equal.
|
// equal.
|
||||||
assert(LHSCst != RHSCst && "Compares not folded above?");
|
assert(LHSCst != RHSCst && "Compares not folded above?");
|
||||||
|
|
||||||
@ -2780,15 +2762,10 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
|||||||
return BinaryOperator::CreateNot(And);
|
return BinaryOperator::CreateNot(And);
|
||||||
}
|
}
|
||||||
|
|
||||||
// (icmp1 A, B) | (icmp2 A, B) --> (icmp3 A, B)
|
if (ICmpInst *RHS = dyn_cast<ICmpInst>(I.getOperand(1)))
|
||||||
if (ICmpInst *RHS = dyn_cast<ICmpInst>(I.getOperand(1))) {
|
|
||||||
if (Instruction *R = AssociativeOpt(I, FoldICmpLogical(*this, RHS)))
|
|
||||||
return R;
|
|
||||||
|
|
||||||
if (ICmpInst *LHS = dyn_cast<ICmpInst>(I.getOperand(0)))
|
if (ICmpInst *LHS = dyn_cast<ICmpInst>(I.getOperand(0)))
|
||||||
if (Instruction *Res = FoldOrOfICmps(I, LHS, RHS))
|
if (Instruction *Res = FoldOrOfICmps(I, LHS, RHS))
|
||||||
return Res;
|
return Res;
|
||||||
}
|
|
||||||
|
|
||||||
// fold (or (cast A), (cast B)) -> (cast (or A, B))
|
// fold (or (cast A), (cast B)) -> (cast (or A, B))
|
||||||
if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
|
if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
|
||||||
@ -3093,8 +3070,23 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
|||||||
|
|
||||||
// (icmp1 A, B) ^ (icmp2 A, B) --> (icmp3 A, B)
|
// (icmp1 A, B) ^ (icmp2 A, B) --> (icmp3 A, B)
|
||||||
if (ICmpInst *RHS = dyn_cast<ICmpInst>(I.getOperand(1)))
|
if (ICmpInst *RHS = dyn_cast<ICmpInst>(I.getOperand(1)))
|
||||||
if (Instruction *R = AssociativeOpt(I, FoldICmpLogical(*this, RHS)))
|
if (ICmpInst *LHS = dyn_cast<ICmpInst>(I.getOperand(0)))
|
||||||
return R;
|
if (PredicatesFoldable(LHS->getPredicate(), RHS->getPredicate())) {
|
||||||
|
if (LHS->getOperand(0) == RHS->getOperand(1) &&
|
||||||
|
LHS->getOperand(1) == RHS->getOperand(0))
|
||||||
|
LHS->swapOperands();
|
||||||
|
if (LHS->getOperand(0) == RHS->getOperand(0) &&
|
||||||
|
LHS->getOperand(1) == RHS->getOperand(1)) {
|
||||||
|
Value *Op0 = LHS->getOperand(0), *Op1 = LHS->getOperand(1);
|
||||||
|
unsigned Code = getICmpCode(LHS) ^ getICmpCode(RHS);
|
||||||
|
bool isSigned = LHS->isSigned() || RHS->isSigned();
|
||||||
|
Value *RV = getICmpValue(isSigned, Code, Op0, Op1);
|
||||||
|
if (Instruction *I = dyn_cast<Instruction>(RV))
|
||||||
|
return I;
|
||||||
|
// Otherwise, it's a constant boolean value.
|
||||||
|
return ReplaceInstUsesWith(I, RV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// fold (xor (cast A), (cast B)) -> (cast (xor A, B))
|
// fold (xor (cast A), (cast B)) -> (cast (xor A, B))
|
||||||
if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
|
if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user