[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp

Robert L. Bocchino Jr. bocchino at persephone.cs.uiuc.edu
Fri Jan 13 14:48:37 PST 2006



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.413 -> 1.414
---
Log message:

Added instcombine support for extractelement.


---
Diffs of the changes:  (+54 -1)

 InstructionCombining.cpp |   55 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 54 insertions(+), 1 deletion(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.413 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.414
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.413	Fri Jan 13 15:28:09 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Fri Jan 13 16:48:06 2006
@@ -135,6 +135,7 @@
     Instruction *visitStoreInst(StoreInst &SI);
     Instruction *visitBranchInst(BranchInst &BI);
     Instruction *visitSwitchInst(SwitchInst &SI);
+    Instruction *visitExtractElementInst(ExtractElementInst &EI);
 
     // visitInstruction - Specify what to return for unhandled instructions...
     Instruction *visitInstruction(Instruction &I) { return 0; }
@@ -5877,6 +5878,58 @@
   return 0;
 }
 
+Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
+  if (ConstantAggregateZero *C = 
+      dyn_cast<ConstantAggregateZero>(EI.getOperand(0))) {
+    // If packed val is constant 0, replace extract with scalar 0
+    const Type *Ty = cast<PackedType>(C->getType())->getElementType();
+    EI.replaceAllUsesWith(Constant::getNullValue(Ty));
+    return ReplaceInstUsesWith(EI, Constant::getNullValue(Ty));
+  }
+  if (ConstantPacked *C = dyn_cast<ConstantPacked>(EI.getOperand(0))) {
+    // If packed val is constant with uniform operands, replace EI
+    // with that operand
+    Constant *op0 = cast<Constant>(C->getOperand(0));
+    for (unsigned i = 1; i < C->getNumOperands(); ++i)
+      if (C->getOperand(i) != op0) return 0;
+    return ReplaceInstUsesWith(EI, op0);
+  }
+  if (Instruction *I = dyn_cast<Instruction>(EI.getOperand(0)))
+    if (I->hasOneUse()) {
+      // Push extractelement into predecessor operation if legal and
+      // profitable to do so
+      if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) {
+        if (!isa<Constant>(BO->getOperand(0)) &&
+            !isa<Constant>(BO->getOperand(1)))
+          return 0;
+        ExtractElementInst *newEI0 = 
+          new ExtractElementInst(BO->getOperand(0), EI.getOperand(1),
+                                 EI.getName());
+        ExtractElementInst *newEI1 =
+          new ExtractElementInst(BO->getOperand(1), EI.getOperand(1),
+                                 EI.getName());
+        InsertNewInstBefore(newEI0, EI);
+        InsertNewInstBefore(newEI1, EI);
+        return BinaryOperator::create(BO->getOpcode(), newEI0, newEI1);
+      }
+      switch(I->getOpcode()) {
+      case Instruction::Load: {
+        Value *Ptr = InsertCastBefore(I->getOperand(0),
+                                      PointerType::get(EI.getType()), EI);
+        GetElementPtrInst *GEP = 
+          new GetElementPtrInst(Ptr, EI.getOperand(1),
+                                I->getName() + ".gep");
+        InsertNewInstBefore(GEP, EI);
+        return new LoadInst(GEP);
+      }
+      default:
+        return 0;
+      }
+    }
+  return 0;
+}
+
+
 void InstCombiner::removeFromWorkList(Instruction *I) {
   WorkList.erase(std::remove(WorkList.begin(), WorkList.end(), I),
                  WorkList.end());
@@ -6075,7 +6128,7 @@
               WorkList.push_back(OpI);
 
           // Instructions may end up in the worklist more than once.  Erase all
-          // occurrances of this instruction.
+          // occurrences of this instruction.
           removeFromWorkList(I);
           I->eraseFromParent();
         } else {






More information about the llvm-commits mailing list