mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-16 22:46:06 +00:00
simplify the conditions on two gigantic if's, decreasing indentation
a bit. Next step is to factor out into their own helper functions. llvm-svn: 59397
This commit is contained in:
parent
a3b2ef6fa9
commit
b37b6e7e96
@ -3240,13 +3240,12 @@ static Value *getFCmpValue(bool isordered, unsigned code,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// PredicatesFoldable - Return true if both predicates match sign or if at
|
||||
/// least one of them is an equality comparison (which is signless).
|
||||
static bool PredicatesFoldable(ICmpInst::Predicate p1, ICmpInst::Predicate p2) {
|
||||
return (ICmpInst::isSignedPredicate(p1) == ICmpInst::isSignedPredicate(p2)) ||
|
||||
(ICmpInst::isSignedPredicate(p1) &&
|
||||
(p2 == ICmpInst::ICMP_EQ || p2 == ICmpInst::ICMP_NE)) ||
|
||||
(ICmpInst::isSignedPredicate(p2) &&
|
||||
(p1 == ICmpInst::ICMP_EQ || p1 == ICmpInst::ICMP_NE));
|
||||
(ICmpInst::isSignedPredicate(p1) && ICmpInst::isEquality(p2)) ||
|
||||
(ICmpInst::isSignedPredicate(p2) && ICmpInst::isEquality(p1));
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -3793,153 +3792,152 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
||||
Value *Val;
|
||||
ConstantInt *LHSCst, *RHSCst;
|
||||
ICmpInst::Predicate LHSCC, RHSCC;
|
||||
if (match(Op0, m_ICmp(LHSCC, m_Value(Val), m_ConstantInt(LHSCst))))
|
||||
if (match(RHS, m_ICmp(RHSCC, m_Specific(Val), m_ConstantInt(RHSCst))))
|
||||
// ICMP_[GL]E X, CST is folded to ICMP_[GL]T elsewhere.
|
||||
if (LHSCC != ICmpInst::ICMP_UGE && LHSCC != ICmpInst::ICMP_ULE &&
|
||||
RHSCC != ICmpInst::ICMP_UGE && RHSCC != ICmpInst::ICMP_ULE &&
|
||||
LHSCC != ICmpInst::ICMP_SGE && LHSCC != ICmpInst::ICMP_SLE &&
|
||||
RHSCC != ICmpInst::ICMP_SGE && RHSCC != ICmpInst::ICMP_SLE &&
|
||||
|
||||
// Don't try to fold ICMP_SLT + ICMP_ULT.
|
||||
(ICmpInst::isEquality(LHSCC) || ICmpInst::isEquality(RHSCC) ||
|
||||
ICmpInst::isSignedPredicate(LHSCC) ==
|
||||
ICmpInst::isSignedPredicate(RHSCC))) {
|
||||
// Ensure that the larger constant is on the RHS.
|
||||
ICmpInst::Predicate GT;
|
||||
if (ICmpInst::isSignedPredicate(LHSCC) ||
|
||||
(ICmpInst::isEquality(LHSCC) &&
|
||||
ICmpInst::isSignedPredicate(RHSCC)))
|
||||
GT = ICmpInst::ICMP_SGT;
|
||||
else
|
||||
GT = ICmpInst::ICMP_UGT;
|
||||
// (icmp1 A, C1) & (icmp2 A, C2) --> something simpler.
|
||||
if (match(Op0, m_ICmp(LHSCC, m_Value(Val), m_ConstantInt(LHSCst))) &&
|
||||
match(RHS, m_ICmp(RHSCC, m_Specific(Val), m_ConstantInt(RHSCst))) &&
|
||||
|
||||
// ICMP_[US][GL]E X, CST is folded to ICMP_[US][GL]T elsewhere.
|
||||
LHSCC != ICmpInst::ICMP_UGE && LHSCC != ICmpInst::ICMP_ULE &&
|
||||
RHSCC != ICmpInst::ICMP_UGE && RHSCC != ICmpInst::ICMP_ULE &&
|
||||
LHSCC != ICmpInst::ICMP_SGE && LHSCC != ICmpInst::ICMP_SLE &&
|
||||
RHSCC != ICmpInst::ICMP_SGE && RHSCC != ICmpInst::ICMP_SLE &&
|
||||
|
||||
Constant *Cmp = ConstantExpr::getICmp(GT, LHSCst, RHSCst);
|
||||
ICmpInst *LHS = cast<ICmpInst>(Op0);
|
||||
if (cast<ConstantInt>(Cmp)->getZExtValue()) {
|
||||
std::swap(LHS, RHS);
|
||||
std::swap(LHSCst, RHSCst);
|
||||
std::swap(LHSCC, RHSCC);
|
||||
}
|
||||
// We can't fold (ugt x, C) & (sgt x, C2).
|
||||
PredicatesFoldable(LHSCC, RHSCC)) {
|
||||
// Ensure that the larger constant is on the RHS.
|
||||
ICmpInst::Predicate GT;
|
||||
if (ICmpInst::isSignedPredicate(LHSCC) ||
|
||||
(ICmpInst::isEquality(LHSCC) &&
|
||||
ICmpInst::isSignedPredicate(RHSCC)))
|
||||
GT = ICmpInst::ICMP_SGT;
|
||||
else
|
||||
GT = ICmpInst::ICMP_UGT;
|
||||
|
||||
Constant *Cmp = ConstantExpr::getICmp(GT, LHSCst, RHSCst);
|
||||
ICmpInst *LHS = cast<ICmpInst>(Op0);
|
||||
if (cast<ConstantInt>(Cmp)->getZExtValue()) {
|
||||
std::swap(LHS, RHS);
|
||||
std::swap(LHSCst, RHSCst);
|
||||
std::swap(LHSCC, RHSCC);
|
||||
}
|
||||
|
||||
// At this point, we know we have have two icmp instructions
|
||||
// comparing a value against two constants and and'ing the result
|
||||
// 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
|
||||
// (from the FoldICmpLogical check above), that the two constants
|
||||
// are not equal and that the larger constant is on the RHS
|
||||
assert(LHSCst != RHSCst && "Compares not folded above?");
|
||||
// At this point, we know we have have two icmp instructions
|
||||
// comparing a value against two constants and and'ing the result
|
||||
// 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
|
||||
// (from the FoldICmpLogical check above), that the two constants
|
||||
// are not equal and that the larger constant is on the RHS
|
||||
assert(LHSCst != RHSCst && "Compares not folded above?");
|
||||
|
||||
switch (LHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X == 13 & X == 15) -> false
|
||||
case ICmpInst::ICMP_UGT: // (X == 13 & X > 15) -> false
|
||||
case ICmpInst::ICMP_SGT: // (X == 13 & X > 15) -> false
|
||||
return ReplaceInstUsesWith(I, ConstantInt::getFalse());
|
||||
case ICmpInst::ICMP_NE: // (X == 13 & X != 15) -> X == 13
|
||||
case ICmpInst::ICMP_ULT: // (X == 13 & X < 15) -> X == 13
|
||||
case ICmpInst::ICMP_SLT: // (X == 13 & X < 15) -> X == 13
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
}
|
||||
case ICmpInst::ICMP_NE:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_ULT:
|
||||
if (LHSCst == SubOne(RHSCst)) // (X != 13 & X u< 14) -> X < 13
|
||||
return new ICmpInst(ICmpInst::ICMP_ULT, Val, LHSCst);
|
||||
break; // (X != 13 & X u< 15) -> no change
|
||||
case ICmpInst::ICMP_SLT:
|
||||
if (LHSCst == SubOne(RHSCst)) // (X != 13 & X s< 14) -> X < 13
|
||||
return new ICmpInst(ICmpInst::ICMP_SLT, Val, LHSCst);
|
||||
break; // (X != 13 & X s< 15) -> no change
|
||||
case ICmpInst::ICMP_EQ: // (X != 13 & X == 15) -> X == 15
|
||||
case ICmpInst::ICMP_UGT: // (X != 13 & X u> 15) -> X u> 15
|
||||
case ICmpInst::ICMP_SGT: // (X != 13 & X s> 15) -> X s> 15
|
||||
return ReplaceInstUsesWith(I, RHS);
|
||||
case ICmpInst::ICMP_NE:
|
||||
if (LHSCst == SubOne(RHSCst)){// (X != 13 & X != 14) -> X-13 >u 1
|
||||
Constant *AddCST = ConstantExpr::getNeg(LHSCst);
|
||||
Instruction *Add = BinaryOperator::CreateAdd(Val, AddCST,
|
||||
Val->getName()+".off");
|
||||
InsertNewInstBefore(Add, I);
|
||||
return new ICmpInst(ICmpInst::ICMP_UGT, Add,
|
||||
ConstantInt::get(Add->getType(), 1));
|
||||
}
|
||||
break; // (X != 13 & X != 15) -> no change
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_ULT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X u< 13 & X == 15) -> false
|
||||
case ICmpInst::ICMP_UGT: // (X u< 13 & X u> 15) -> false
|
||||
return ReplaceInstUsesWith(I, ConstantInt::getFalse());
|
||||
case ICmpInst::ICMP_SGT: // (X u< 13 & X s> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE: // (X u< 13 & X != 15) -> X u< 13
|
||||
case ICmpInst::ICMP_ULT: // (X u< 13 & X u< 15) -> X u< 13
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
case ICmpInst::ICMP_SLT: // (X u< 13 & X s< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_SLT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X s< 13 & X == 15) -> false
|
||||
case ICmpInst::ICMP_SGT: // (X s< 13 & X s> 15) -> false
|
||||
return ReplaceInstUsesWith(I, ConstantInt::getFalse());
|
||||
case ICmpInst::ICMP_UGT: // (X s< 13 & X u> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE: // (X s< 13 & X != 15) -> X < 13
|
||||
case ICmpInst::ICMP_SLT: // (X s< 13 & X s< 15) -> X < 13
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
case ICmpInst::ICMP_ULT: // (X s< 13 & X u< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_UGT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X u> 13 & X == 15) -> X == 15
|
||||
case ICmpInst::ICMP_UGT: // (X u> 13 & X u> 15) -> X u> 15
|
||||
return ReplaceInstUsesWith(I, RHS);
|
||||
case ICmpInst::ICMP_SGT: // (X u> 13 & X s> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE:
|
||||
if (RHSCst == AddOne(LHSCst)) // (X u> 13 & X != 14) -> X u> 14
|
||||
return new ICmpInst(LHSCC, Val, RHSCst);
|
||||
break; // (X u> 13 & X != 15) -> no change
|
||||
case ICmpInst::ICMP_ULT: // (X u> 13 & X u< 15) ->(X-14) <u 1
|
||||
return InsertRangeTest(Val, AddOne(LHSCst), RHSCst, false,
|
||||
true, I);
|
||||
case ICmpInst::ICMP_SLT: // (X u> 13 & X s< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_SGT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X s> 13 & X == 15) -> X == 15
|
||||
case ICmpInst::ICMP_SGT: // (X s> 13 & X s> 15) -> X s> 15
|
||||
return ReplaceInstUsesWith(I, RHS);
|
||||
case ICmpInst::ICMP_UGT: // (X s> 13 & X u> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE:
|
||||
if (RHSCst == AddOne(LHSCst)) // (X s> 13 & X != 14) -> X s> 14
|
||||
return new ICmpInst(LHSCC, Val, RHSCst);
|
||||
break; // (X s> 13 & X != 15) -> no change
|
||||
case ICmpInst::ICMP_SLT: // (X s> 13 & X s< 15) ->(X-14) s< 1
|
||||
return InsertRangeTest(Val, AddOne(LHSCst), RHSCst, true, true,I);
|
||||
case ICmpInst::ICMP_ULT: // (X s> 13 & X u< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (LHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X == 13 & X == 15) -> false
|
||||
case ICmpInst::ICMP_UGT: // (X == 13 & X > 15) -> false
|
||||
case ICmpInst::ICMP_SGT: // (X == 13 & X > 15) -> false
|
||||
return ReplaceInstUsesWith(I, ConstantInt::getFalse());
|
||||
case ICmpInst::ICMP_NE: // (X == 13 & X != 15) -> X == 13
|
||||
case ICmpInst::ICMP_ULT: // (X == 13 & X < 15) -> X == 13
|
||||
case ICmpInst::ICMP_SLT: // (X == 13 & X < 15) -> X == 13
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
}
|
||||
case ICmpInst::ICMP_NE:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_ULT:
|
||||
if (LHSCst == SubOne(RHSCst)) // (X != 13 & X u< 14) -> X < 13
|
||||
return new ICmpInst(ICmpInst::ICMP_ULT, Val, LHSCst);
|
||||
break; // (X != 13 & X u< 15) -> no change
|
||||
case ICmpInst::ICMP_SLT:
|
||||
if (LHSCst == SubOne(RHSCst)) // (X != 13 & X s< 14) -> X < 13
|
||||
return new ICmpInst(ICmpInst::ICMP_SLT, Val, LHSCst);
|
||||
break; // (X != 13 & X s< 15) -> no change
|
||||
case ICmpInst::ICMP_EQ: // (X != 13 & X == 15) -> X == 15
|
||||
case ICmpInst::ICMP_UGT: // (X != 13 & X u> 15) -> X u> 15
|
||||
case ICmpInst::ICMP_SGT: // (X != 13 & X s> 15) -> X s> 15
|
||||
return ReplaceInstUsesWith(I, RHS);
|
||||
case ICmpInst::ICMP_NE:
|
||||
if (LHSCst == SubOne(RHSCst)){// (X != 13 & X != 14) -> X-13 >u 1
|
||||
Constant *AddCST = ConstantExpr::getNeg(LHSCst);
|
||||
Instruction *Add = BinaryOperator::CreateAdd(Val, AddCST,
|
||||
Val->getName()+".off");
|
||||
InsertNewInstBefore(Add, I);
|
||||
return new ICmpInst(ICmpInst::ICMP_UGT, Add,
|
||||
ConstantInt::get(Add->getType(), 1));
|
||||
}
|
||||
break; // (X != 13 & X != 15) -> no change
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_ULT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X u< 13 & X == 15) -> false
|
||||
case ICmpInst::ICMP_UGT: // (X u< 13 & X u> 15) -> false
|
||||
return ReplaceInstUsesWith(I, ConstantInt::getFalse());
|
||||
case ICmpInst::ICMP_SGT: // (X u< 13 & X s> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE: // (X u< 13 & X != 15) -> X u< 13
|
||||
case ICmpInst::ICMP_ULT: // (X u< 13 & X u< 15) -> X u< 13
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
case ICmpInst::ICMP_SLT: // (X u< 13 & X s< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_SLT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X s< 13 & X == 15) -> false
|
||||
case ICmpInst::ICMP_SGT: // (X s< 13 & X s> 15) -> false
|
||||
return ReplaceInstUsesWith(I, ConstantInt::getFalse());
|
||||
case ICmpInst::ICMP_UGT: // (X s< 13 & X u> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE: // (X s< 13 & X != 15) -> X < 13
|
||||
case ICmpInst::ICMP_SLT: // (X s< 13 & X s< 15) -> X < 13
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
case ICmpInst::ICMP_ULT: // (X s< 13 & X u< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_UGT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X u> 13 & X == 15) -> X == 15
|
||||
case ICmpInst::ICMP_UGT: // (X u> 13 & X u> 15) -> X u> 15
|
||||
return ReplaceInstUsesWith(I, RHS);
|
||||
case ICmpInst::ICMP_SGT: // (X u> 13 & X s> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE:
|
||||
if (RHSCst == AddOne(LHSCst)) // (X u> 13 & X != 14) -> X u> 14
|
||||
return new ICmpInst(LHSCC, Val, RHSCst);
|
||||
break; // (X u> 13 & X != 15) -> no change
|
||||
case ICmpInst::ICMP_ULT: // (X u> 13 & X u< 15) ->(X-14) <u 1
|
||||
return InsertRangeTest(Val, AddOne(LHSCst), RHSCst, false, true, I);
|
||||
case ICmpInst::ICMP_SLT: // (X u> 13 & X s< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_SGT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X s> 13 & X == 15) -> X == 15
|
||||
case ICmpInst::ICMP_SGT: // (X s> 13 & X s> 15) -> X s> 15
|
||||
return ReplaceInstUsesWith(I, RHS);
|
||||
case ICmpInst::ICMP_UGT: // (X s> 13 & X u> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE:
|
||||
if (RHSCst == AddOne(LHSCst)) // (X s> 13 & X != 14) -> X s> 14
|
||||
return new ICmpInst(LHSCC, Val, RHSCst);
|
||||
break; // (X s> 13 & X != 15) -> no change
|
||||
case ICmpInst::ICMP_SLT: // (X s> 13 & X s< 15) ->(X-14) s< 1
|
||||
return InsertRangeTest(Val, AddOne(LHSCst), RHSCst, true, true, I);
|
||||
case ICmpInst::ICMP_ULT: // (X s> 13 & X u< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fold (and (cast A), (cast B)) -> (cast (and A, B))
|
||||
@ -4427,149 +4425,150 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
||||
Value *Val;
|
||||
ConstantInt *LHSCst, *RHSCst;
|
||||
ICmpInst::Predicate LHSCC, RHSCC;
|
||||
if (match(Op0, m_ICmp(LHSCC, m_Value(Val), m_ConstantInt(LHSCst))))
|
||||
if (match(RHS, m_ICmp(RHSCC, m_Specific(Val), m_ConstantInt(RHSCst))))
|
||||
// icmp [us][gl]e x, cst is folded to icmp [us][gl]t elsewhere.
|
||||
if (LHSCC != ICmpInst::ICMP_UGE && LHSCC != ICmpInst::ICMP_ULE &&
|
||||
RHSCC != ICmpInst::ICMP_UGE && RHSCC != ICmpInst::ICMP_ULE &&
|
||||
LHSCC != ICmpInst::ICMP_SGE && LHSCC != ICmpInst::ICMP_SLE &&
|
||||
RHSCC != ICmpInst::ICMP_SGE && RHSCC != ICmpInst::ICMP_SLE &&
|
||||
// We can't fold (ugt x, C) | (sgt x, C2).
|
||||
PredicatesFoldable(LHSCC, RHSCC)) {
|
||||
// Ensure that the larger constant is on the RHS.
|
||||
ICmpInst *LHS = cast<ICmpInst>(Op0);
|
||||
bool NeedsSwap;
|
||||
if (ICmpInst::isEquality(LHSCC) ? ICmpInst::isSignedPredicate(RHSCC)
|
||||
: ICmpInst::isSignedPredicate(LHSCC))
|
||||
NeedsSwap = LHSCst->getValue().sgt(RHSCst->getValue());
|
||||
else
|
||||
NeedsSwap = LHSCst->getValue().ugt(RHSCst->getValue());
|
||||
|
||||
if (NeedsSwap) {
|
||||
std::swap(LHS, RHS);
|
||||
std::swap(LHSCst, RHSCst);
|
||||
std::swap(LHSCC, RHSCC);
|
||||
}
|
||||
// (icmp1 A, C1) | (icmp2 A, C2) --> something simpler.
|
||||
if (match(Op0, m_ICmp(LHSCC, m_Value(Val), m_ConstantInt(LHSCst))) &&
|
||||
match(RHS, m_ICmp(RHSCC, m_Specific(Val), m_ConstantInt(RHSCst))) &&
|
||||
|
||||
// ICMP_[US][GL]E X, CST is folded to ICMP_[US][GL]T elsewhere.
|
||||
LHSCC != ICmpInst::ICMP_UGE && LHSCC != ICmpInst::ICMP_ULE &&
|
||||
RHSCC != ICmpInst::ICMP_UGE && RHSCC != ICmpInst::ICMP_ULE &&
|
||||
LHSCC != ICmpInst::ICMP_SGE && LHSCC != ICmpInst::ICMP_SLE &&
|
||||
RHSCC != ICmpInst::ICMP_SGE && RHSCC != ICmpInst::ICMP_SLE &&
|
||||
|
||||
// We can't fold (ugt x, C) | (sgt x, C2).
|
||||
PredicatesFoldable(LHSCC, RHSCC)) {
|
||||
// Ensure that the larger constant is on the RHS.
|
||||
ICmpInst *LHS = cast<ICmpInst>(Op0);
|
||||
bool NeedsSwap;
|
||||
if (ICmpInst::isEquality(LHSCC) ? ICmpInst::isSignedPredicate(RHSCC)
|
||||
: ICmpInst::isSignedPredicate(LHSCC))
|
||||
NeedsSwap = LHSCst->getValue().sgt(RHSCst->getValue());
|
||||
else
|
||||
NeedsSwap = LHSCst->getValue().ugt(RHSCst->getValue());
|
||||
|
||||
if (NeedsSwap) {
|
||||
std::swap(LHS, RHS);
|
||||
std::swap(LHSCst, RHSCst);
|
||||
std::swap(LHSCC, RHSCC);
|
||||
}
|
||||
|
||||
// At this point, we know we have have two icmp instructions
|
||||
// comparing a value against two constants and or'ing the result
|
||||
// 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
|
||||
// FoldICmpLogical check above), that the two constants are not
|
||||
// equal.
|
||||
assert(LHSCst != RHSCst && "Compares not folded above?");
|
||||
// At this point, we know we have have two icmp instructions
|
||||
// comparing a value against two constants and or'ing the result
|
||||
// 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
|
||||
// FoldICmpLogical check above), that the two constants are not
|
||||
// equal.
|
||||
assert(LHSCst != RHSCst && "Compares not folded above?");
|
||||
|
||||
switch (LHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ:
|
||||
if (LHSCst == SubOne(RHSCst)) {// (X == 13 | X == 14) -> X-13 <u 2
|
||||
Constant *AddCST = ConstantExpr::getNeg(LHSCst);
|
||||
Instruction *Add = BinaryOperator::CreateAdd(Val, AddCST,
|
||||
Val->getName()+".off");
|
||||
InsertNewInstBefore(Add, I);
|
||||
AddCST = Subtract(AddOne(RHSCst), LHSCst);
|
||||
return new ICmpInst(ICmpInst::ICMP_ULT, Add, AddCST);
|
||||
}
|
||||
break; // (X == 13 | X == 15) -> no change
|
||||
case ICmpInst::ICMP_UGT: // (X == 13 | X u> 14) -> no change
|
||||
case ICmpInst::ICMP_SGT: // (X == 13 | X s> 14) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE: // (X == 13 | X != 15) -> X != 15
|
||||
case ICmpInst::ICMP_ULT: // (X == 13 | X u< 15) -> X u< 15
|
||||
case ICmpInst::ICMP_SLT: // (X == 13 | X s< 15) -> X s< 15
|
||||
return ReplaceInstUsesWith(I, RHS);
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_NE:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X != 13 | X == 15) -> X != 13
|
||||
case ICmpInst::ICMP_UGT: // (X != 13 | X u> 15) -> X != 13
|
||||
case ICmpInst::ICMP_SGT: // (X != 13 | X s> 15) -> X != 13
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
case ICmpInst::ICMP_NE: // (X != 13 | X != 15) -> true
|
||||
case ICmpInst::ICMP_ULT: // (X != 13 | X u< 15) -> true
|
||||
case ICmpInst::ICMP_SLT: // (X != 13 | X s< 15) -> true
|
||||
return ReplaceInstUsesWith(I, ConstantInt::getTrue());
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_ULT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X u< 13 | X == 14) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_UGT: // (X u< 13 | X u> 15) ->(X-13) u> 2
|
||||
// If RHSCst is [us]MAXINT, it is always false. Not handling
|
||||
// this can cause overflow.
|
||||
if (RHSCst->isMaxValue(false))
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
return InsertRangeTest(Val, LHSCst, AddOne(RHSCst), false,
|
||||
false, I);
|
||||
case ICmpInst::ICMP_SGT: // (X u< 13 | X s> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE: // (X u< 13 | X != 15) -> X != 15
|
||||
case ICmpInst::ICMP_ULT: // (X u< 13 | X u< 15) -> X u< 15
|
||||
return ReplaceInstUsesWith(I, RHS);
|
||||
case ICmpInst::ICMP_SLT: // (X u< 13 | X s< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_SLT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X s< 13 | X == 14) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_SGT: // (X s< 13 | X s> 15) ->(X-13) s> 2
|
||||
// If RHSCst is [us]MAXINT, it is always false. Not handling
|
||||
// this can cause overflow.
|
||||
if (RHSCst->isMaxValue(true))
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
return InsertRangeTest(Val, LHSCst, AddOne(RHSCst), true,
|
||||
false, I);
|
||||
case ICmpInst::ICMP_UGT: // (X s< 13 | X u> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE: // (X s< 13 | X != 15) -> X != 15
|
||||
case ICmpInst::ICMP_SLT: // (X s< 13 | X s< 15) -> X s< 15
|
||||
return ReplaceInstUsesWith(I, RHS);
|
||||
case ICmpInst::ICMP_ULT: // (X s< 13 | X u< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_UGT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X u> 13 | X == 15) -> X u> 13
|
||||
case ICmpInst::ICMP_UGT: // (X u> 13 | X u> 15) -> X u> 13
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
case ICmpInst::ICMP_SGT: // (X u> 13 | X s> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE: // (X u> 13 | X != 15) -> true
|
||||
case ICmpInst::ICMP_ULT: // (X u> 13 | X u< 15) -> true
|
||||
return ReplaceInstUsesWith(I, ConstantInt::getTrue());
|
||||
case ICmpInst::ICMP_SLT: // (X u> 13 | X s< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_SGT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X s> 13 | X == 15) -> X > 13
|
||||
case ICmpInst::ICMP_SGT: // (X s> 13 | X s> 15) -> X > 13
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
case ICmpInst::ICMP_UGT: // (X s> 13 | X u> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE: // (X s> 13 | X != 15) -> true
|
||||
case ICmpInst::ICMP_SLT: // (X s> 13 | X s< 15) -> true
|
||||
return ReplaceInstUsesWith(I, ConstantInt::getTrue());
|
||||
case ICmpInst::ICMP_ULT: // (X s> 13 | X u< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
switch (LHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ:
|
||||
if (LHSCst == SubOne(RHSCst)) { // (X == 13 | X == 14) -> X-13 <u 2
|
||||
Constant *AddCST = ConstantExpr::getNeg(LHSCst);
|
||||
Instruction *Add = BinaryOperator::CreateAdd(Val, AddCST,
|
||||
Val->getName()+".off");
|
||||
InsertNewInstBefore(Add, I);
|
||||
AddCST = Subtract(AddOne(RHSCst), LHSCst);
|
||||
return new ICmpInst(ICmpInst::ICMP_ULT, Add, AddCST);
|
||||
}
|
||||
break; // (X == 13 | X == 15) -> no change
|
||||
case ICmpInst::ICMP_UGT: // (X == 13 | X u> 14) -> no change
|
||||
case ICmpInst::ICMP_SGT: // (X == 13 | X s> 14) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE: // (X == 13 | X != 15) -> X != 15
|
||||
case ICmpInst::ICMP_ULT: // (X == 13 | X u< 15) -> X u< 15
|
||||
case ICmpInst::ICMP_SLT: // (X == 13 | X s< 15) -> X s< 15
|
||||
return ReplaceInstUsesWith(I, RHS);
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_NE:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X != 13 | X == 15) -> X != 13
|
||||
case ICmpInst::ICMP_UGT: // (X != 13 | X u> 15) -> X != 13
|
||||
case ICmpInst::ICMP_SGT: // (X != 13 | X s> 15) -> X != 13
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
case ICmpInst::ICMP_NE: // (X != 13 | X != 15) -> true
|
||||
case ICmpInst::ICMP_ULT: // (X != 13 | X u< 15) -> true
|
||||
case ICmpInst::ICMP_SLT: // (X != 13 | X s< 15) -> true
|
||||
return ReplaceInstUsesWith(I, ConstantInt::getTrue());
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_ULT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X u< 13 | X == 14) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_UGT: // (X u< 13 | X u> 15) -> (X-13) u> 2
|
||||
// If RHSCst is [us]MAXINT, it is always false. Not handling
|
||||
// this can cause overflow.
|
||||
if (RHSCst->isMaxValue(false))
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
return InsertRangeTest(Val, LHSCst, AddOne(RHSCst), false, false, I);
|
||||
case ICmpInst::ICMP_SGT: // (X u< 13 | X s> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE: // (X u< 13 | X != 15) -> X != 15
|
||||
case ICmpInst::ICMP_ULT: // (X u< 13 | X u< 15) -> X u< 15
|
||||
return ReplaceInstUsesWith(I, RHS);
|
||||
case ICmpInst::ICMP_SLT: // (X u< 13 | X s< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_SLT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X s< 13 | X == 14) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_SGT: // (X s< 13 | X s> 15) -> (X-13) s> 2
|
||||
// If RHSCst is [us]MAXINT, it is always false. Not handling
|
||||
// this can cause overflow.
|
||||
if (RHSCst->isMaxValue(true))
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
return InsertRangeTest(Val, LHSCst, AddOne(RHSCst), true, false, I);
|
||||
case ICmpInst::ICMP_UGT: // (X s< 13 | X u> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE: // (X s< 13 | X != 15) -> X != 15
|
||||
case ICmpInst::ICMP_SLT: // (X s< 13 | X s< 15) -> X s< 15
|
||||
return ReplaceInstUsesWith(I, RHS);
|
||||
case ICmpInst::ICMP_ULT: // (X s< 13 | X u< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_UGT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X u> 13 | X == 15) -> X u> 13
|
||||
case ICmpInst::ICMP_UGT: // (X u> 13 | X u> 15) -> X u> 13
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
case ICmpInst::ICMP_SGT: // (X u> 13 | X s> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE: // (X u> 13 | X != 15) -> true
|
||||
case ICmpInst::ICMP_ULT: // (X u> 13 | X u< 15) -> true
|
||||
return ReplaceInstUsesWith(I, ConstantInt::getTrue());
|
||||
case ICmpInst::ICMP_SLT: // (X u> 13 | X s< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICmpInst::ICMP_SGT:
|
||||
switch (RHSCC) {
|
||||
default: assert(0 && "Unknown integer condition code!");
|
||||
case ICmpInst::ICMP_EQ: // (X s> 13 | X == 15) -> X > 13
|
||||
case ICmpInst::ICMP_SGT: // (X s> 13 | X s> 15) -> X > 13
|
||||
return ReplaceInstUsesWith(I, LHS);
|
||||
case ICmpInst::ICMP_UGT: // (X s> 13 | X u> 15) -> no change
|
||||
break;
|
||||
case ICmpInst::ICMP_NE: // (X s> 13 | X != 15) -> true
|
||||
case ICmpInst::ICMP_SLT: // (X s> 13 | X s< 15) -> true
|
||||
return ReplaceInstUsesWith(I, ConstantInt::getTrue());
|
||||
case ICmpInst::ICMP_ULT: // (X s> 13 | X u< 15) -> no change
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fold (or (cast A), (cast B)) -> (cast (or A, B))
|
||||
|
Loading…
x
Reference in New Issue
Block a user