aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-11-16 04:55:20 +0000
committerChris Lattner <sabre@nondot.org>2008-11-16 04:55:20 +0000
commit2972b827b3d16c5676259be42bbb7fadbaba012e (patch)
treece2150f487f97e0f2291a350fb7e3389ce446140 /lib
parent641ea46c8765a2ac3b525b5ec8a5496849f26c8d (diff)
downloadexternal_llvm-2972b827b3d16c5676259be42bbb7fadbaba012e.zip
external_llvm-2972b827b3d16c5676259be42bbb7fadbaba012e.tar.gz
external_llvm-2972b827b3d16c5676259be42bbb7fadbaba012e.tar.bz2
simplify the conditions on two gigantic if's, decreasing indentation
a bit. Next step is to factor out into their own helper functions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59397 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp579
1 files changed, 289 insertions, 290 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 042dc88..c23133d 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -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);
- }
-
- // 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;
+ // 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?");
+
+ 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);
- }
-
- // 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;
+ // (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?");
+
+ 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))