add some trivial support for extractelement.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26928 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 2744c41..041340e 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -821,6 +821,56 @@
       if (Tmp1.Val) Result = Tmp1;
     }
     break;
+  
+  case ISD::EXTRACT_VECTOR_ELT:
+    Tmp1 = LegalizeOp(Node->getOperand(0));
+    Tmp2 = LegalizeOp(Node->getOperand(1));
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+    // FIXME: LOWER.
+    break;
+
+  case ISD::VEXTRACT_VECTOR_ELT:
+    // We know that operand #0 is the Vec vector.  If the index is a constant
+    // or if the invec is a supported hardware type, we can use it.  Otherwise,
+    // lower to a store then an indexed load.
+    Tmp1 = Node->getOperand(0);
+    Tmp2 = LegalizeOp(Node->getOperand(1));
+    
+    SDNode *InVal = Tmp1.Val;
+    unsigned NumElems = cast<ConstantSDNode>(*(InVal->op_end()-2))->getValue();
+    MVT::ValueType EVT = cast<VTSDNode>(*(InVal->op_end()-1))->getVT();
+    
+    // Figure out if there is a Packed type corresponding to this Vector
+    // type.  If so, convert to the packed type.
+    MVT::ValueType TVT = MVT::getVectorType(EVT, NumElems);
+    if (TVT != MVT::Other && TLI.isTypeLegal(TVT)) {
+      // Turn this into a packed extract_vector_elt operation.
+      Tmp1 = PackVectorOp(Tmp1, TVT);
+      Result = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, Node->getValueType(0),
+                           Tmp1, Tmp2);
+      break;
+    } else if (NumElems == 1) {
+      // This must be an access of the only element.
+      Result = PackVectorOp(Tmp1, EVT);
+      break;
+    } else if (ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Tmp2)) {
+      SDOperand Lo, Hi;
+      SplitVectorOp(Tmp1, Lo, Hi);
+      if (CIdx->getValue() < NumElems/2) {
+        Tmp1 = Lo;
+      } else {
+        Tmp1 = Hi;
+        Tmp2 = DAG.getConstant(CIdx->getValue() - NumElems/2,
+                               Tmp2.getValueType());
+      }
+
+      // It's now an extract from the appropriate high or low part.
+      Result = LegalizeOp(DAG.UpdateNodeOperands(Result, Tmp1, Tmp2));
+    } else {
+      // FIXME: IMPLEMENT STORE/LOAD lowering.
+      assert(0 && "unimp!");
+    }
+    break;
     
   case ISD::CALLSEQ_START: {
     SDNode *CallEnd = FindCallEndFromCallStart(Node);
@@ -4264,7 +4314,7 @@
                                              MVT::ValueType NewVT) {
   // FIXME: THIS IS A TEMPORARY HACK
   if (Op.getValueType() == NewVT) return Op;
-  
+    
   assert(Op.getValueType() == MVT::Vector && "Bad PackVectorOp invocation!");
   SDNode *Node = Op.Val;
   
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 8bf499e..fcca7e3 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2671,6 +2671,8 @@
   case ISD::SELECT_CC:   return "select_cc";
   case ISD::INSERT_VECTOR_ELT: return "insert_vector_elt";
   case ISD::VINSERT_VECTOR_ELT: return "vinsert_vector_elt";
+  case ISD::EXTRACT_VECTOR_ELT: return "extract_vector_elt";
+  case ISD::VEXTRACT_VECTOR_ELT: return "vextract_vector_elt";
   case ISD::SCALAR_TO_VECTOR:   return "scalar_to_vector";
   case ISD::VBUILD_VECTOR: return "vbuild_vector";
   case ISD::VECTOR_SHUFFLE: return "vector_shuffle";
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index d59184b..50cb958 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -463,7 +463,7 @@
   void visitSetLT(User &I) { visitSetCC(I, ISD::SETLT, ISD::SETULT); }
   void visitSetGT(User &I) { visitSetCC(I, ISD::SETGT, ISD::SETUGT); }
 
-  void visitExtractElement(ExtractElementInst &I) { assert(0 && "TODO"); }
+  void visitExtractElement(ExtractElementInst &I);
   void visitInsertElement(InsertElementInst &I);
 
   void visitGetElementPtr(User &I);
@@ -853,6 +853,14 @@
                            InVec, InVal, InIdx, Num, Typ));
 }
 
+void SelectionDAGLowering::visitExtractElement(ExtractElementInst &I) {
+  SDOperand InVec = getValue(I.getOperand(0));
+  SDOperand InIdx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(),
+                                getValue(I.getOperand(1)));
+  SDOperand Typ = *(InVec.Val->op_end()-1);
+  setValue(&I, DAG.getNode(ISD::VEXTRACT_VECTOR_ELT,
+                           TLI.getValueType(I.getType()), InVec, InIdx));
+}
 
 void SelectionDAGLowering::visitGetElementPtr(User &I) {
   SDOperand N = getValue(I.getOperand(0));