diff options
author | Chris Lattner <sabre@nondot.org> | 2008-11-16 04:55:20 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-11-16 04:55:20 +0000 |
commit | 2972b827b3d16c5676259be42bbb7fadbaba012e (patch) | |
tree | ce2150f487f97e0f2291a350fb7e3389ce446140 /lib | |
parent | 641ea46c8765a2ac3b525b5ec8a5496849f26c8d (diff) | |
download | external_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.cpp | 579 |
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)) |