Implement Transforms/InstCombine/cast.ll:test13, a case which occurs in a
authorChris Lattner <sabre@nondot.org>
Sun, 22 Feb 2004 05:25:17 +0000 (05:25 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 22 Feb 2004 05:25:17 +0000 (05:25 +0000)
hot 164.gzip loop.

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

lib/Transforms/Scalar/InstructionCombining.cpp
lib/Transforms/Scalar/TailDuplication.cpp

index b89785db9611ae11e73ec8fe880560d0b8a1f892..4c9cc0a29a84ec6c3613013dfa308f680061b2a8 100644 (file)
@@ -2004,9 +2004,14 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
 Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
   // Is it 'getelementptr %P, long 0'  or 'getelementptr %P'
   // If so, eliminate the noop.
-  if ((GEP.getNumOperands() == 2 &&
-       GEP.getOperand(1) == Constant::getNullValue(Type::LongTy)) ||
-      GEP.getNumOperands() == 1)
+  if (GEP.getNumOperands() == 1)
+    return ReplaceInstUsesWith(GEP, GEP.getOperand(0));
+
+  bool HasZeroPointerIndex = false;
+  if (Constant *C = dyn_cast<Constant>(GEP.getOperand(1)))
+    HasZeroPointerIndex = C->isNullValue();
+
+  if (GEP.getNumOperands() == 2 && HasZeroPointerIndex)
     return ReplaceInstUsesWith(GEP, GEP.getOperand(0));
 
   // Combine Indices - If the source pointer to this getelementptr instruction
@@ -2073,6 +2078,31 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
       // Replace all uses of the GEP with the new constexpr...
       return ReplaceInstUsesWith(GEP, CE);
     }
+  } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(GEP.getOperand(0))) {
+    if (CE->getOpcode() == Instruction::Cast) {
+      if (HasZeroPointerIndex) {
+        // transform: GEP (cast [10 x ubyte]* X to [0 x ubyte]*), long 0, ...
+        // into     : GEP [10 x ubyte]* X, long 0, ...
+        //
+        // This occurs when the program declares an array extern like "int X[];"
+        //
+        Constant *X = CE->getOperand(0);
+        const PointerType *CPTy = cast<PointerType>(CE->getType());
+        if (const PointerType *XTy = dyn_cast<PointerType>(X->getType()))
+          if (const ArrayType *XATy =
+              dyn_cast<ArrayType>(XTy->getElementType()))
+            if (const ArrayType *CATy =
+                dyn_cast<ArrayType>(CPTy->getElementType()))
+              if (CATy->getElementType() == XATy->getElementType()) {
+                // At this point, we know that the cast source type is a pointer
+                // to an array of the same type as the destination pointer
+                // array.  Because the array type is never stepped over (there
+                // is a leading zero) we can fold the cast into this GEP.
+                GEP.setOperand(0, X);
+                return &GEP;
+              }
+      }
+    }
   }
 
   return 0;
index 52552d5b094fd3c895f54b77483521b2c202232c..7d5aac4fe73394f3b601f82d51fa1a40b36ea512 100644 (file)
@@ -126,7 +126,8 @@ bool TailDup::canEliminateUnconditionalBranch(TerminatorInst *TI) {
   // Basically, we refuse to make the transformation if any of the values
   // computed in the 'tail' are used in any other basic blocks.
   BasicBlock *Tail = TI->getSuccessor(0);
-
+  assert(isa<BranchInst>(TI) && cast<BranchInst>(TI)->isUnconditional());
+  
   for (BasicBlock::iterator I = Tail->begin(), E = Tail->end(); I != E; ++I)
     for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E;
          ++UI) {