Implement vector expand support for shuffle_vector.  This fixes PR1811.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44242 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index e343a0e..a2f4827 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -6286,6 +6286,41 @@
                                        TLI.getPointerTy()));
     break;
   }
+  case ISD::VECTOR_SHUFFLE: {
+    // Build the low part.
+    SDOperand Mask = Node->getOperand(2);
+    SmallVector<SDOperand, 8> Ops;
+    MVT::ValueType PtrVT = TLI.getPointerTy();
+    
+    // Insert all of the elements from the input that are needed.  We use 
+    // buildvector of extractelement here because the input vectors will have
+    // to be legalized, so this makes the code simpler.
+    for (unsigned i = 0; i != NewNumElts_Lo; ++i) {
+      unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
+      SDOperand InVec = Node->getOperand(0);
+      if (Idx >= NumElements) {
+        InVec = Node->getOperand(1);
+        Idx -= NumElements;
+      }
+      Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, InVec,
+                                DAG.getConstant(Idx, PtrVT)));
+    }
+    Lo = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &Ops[0], Ops.size());
+    Ops.clear();
+    
+    for (unsigned i = NewNumElts_Lo; i != NumElements; ++i) {
+      unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
+      SDOperand InVec = Node->getOperand(0);
+      if (Idx >= NumElements) {
+        InVec = Node->getOperand(1);
+        Idx -= NumElements;
+      }
+      Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, InVec,
+                                DAG.getConstant(Idx, PtrVT)));
+    }
+    Hi = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &Ops[0], Ops.size());
+    break;
+  }
   case ISD::BUILD_VECTOR: {
     SmallVector<SDOperand, 8> LoOps(Node->op_begin(), 
                                     Node->op_begin()+NewNumElts_Lo);