[llvm-commits] [llvm] r59397 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp

Chris Lattner sabre at nondot.org
Sat Nov 15 20:55:20 PST 2008


Author: lattner
Date: Sat Nov 15 22:55:20 2008
New Revision: 59397

URL: http://llvm.org/viewvc/llvm-project?rev=59397&view=rev
Log:
simplify the conditions on two gigantic if's, decreasing indentation
a bit.  Next step is to factor out into their own helper functions.

Modified:
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=59397&r1=59396&r2=59397&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sat Nov 15 22:55:20 2008
@@ -3240,13 +3240,12 @@
   }
 }
 
-
+/// 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 @@
     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 @@
     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))





More information about the llvm-commits mailing list