if two gep comparisons only differ by one index, compare that index directly.
authorChris Lattner <sabre@nondot.org>
Fri, 14 Jan 2005 00:20:05 +0000 (00:20 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 14 Jan 2005 00:20:05 +0000 (00:20 +0000)
This allows us to better optimize begin() -> end() comparisons in common cases.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19542 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index e8f52d11573cfc2b4541fed8ed52f1ae91ecc0d8..948eb329040bf13ad18bb9175e8bd809465690d5 100644 (file)
@@ -2219,6 +2219,8 @@ Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS,
     if (AllZeros)
       return FoldGEPSetCC(GEPRHS, GEPLHS->getOperand(0),
                           SetCondInst::getSwappedCondition(Cond), I);
+
+    // If the other GEP has all zero indices, recurse.
     AllZeros = true;
     for (unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)
       if (!isa<Constant>(GEPRHS->getOperand(i)) ||
@@ -2229,6 +2231,32 @@ Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS,
     if (AllZeros)
       return FoldGEPSetCC(GEPLHS, GEPRHS->getOperand(0), Cond, I);
 
+    if (GEPLHS->getNumOperands() == GEPRHS->getNumOperands()) {
+      // If the GEPs only differ by one index, compare it.
+      unsigned NumDifferences = 0;  // Keep track of # differences.
+      unsigned DiffOperand = 0;     // The operand that differs.
+      for (unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)
+        if (GEPLHS->getOperand(i) != GEPRHS->getOperand(i)) {
+          if (GEPLHS->getOperand(i)->getType() != 
+                     GEPRHS->getOperand(i)->getType()) {
+            // Irreconsilable differences.
+            NumDifferences = 2;
+            break;
+          } else {
+            if (NumDifferences++) break;
+            DiffOperand = i;
+          }
+        }
+
+      if (NumDifferences == 0)   // SAME GEP?
+        return ReplaceInstUsesWith(I, // No comparison is needed here.
+                                 ConstantBool::get(Cond == Instruction::SetEQ));
+      else if (NumDifferences == 1) {
+        return new SetCondInst(Cond, GEPLHS->getOperand(DiffOperand),
+                               GEPRHS->getOperand(DiffOperand));
+      }
+    }
+
     // Only lower this if the setcc is the only user of the GEP or if we expect
     // the result to fold to a constant!
     if ((isa<ConstantExpr>(GEPLHS) || GEPLHS->hasOneUse()) &&