Teach LLVM how to scalarize packed types.  Currently, this only works on
packed types with an element count of 1, although more generic support is
coming.  This allows LLVM to turn the following code:

void %foo(<1 x float> * %a) {
entry:
  %tmp1 = load <1 x float> * %a;
  %tmp2 = add <1 x float> %tmp1, %tmp1
  store <1 x float> %tmp2, <1 x float> *%a
  ret void
}

Into:

_foo:
        lfs f0, 0(r3)
        fadds f0, f0, f0
        stfs f0, 0(r3)
        blr


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24416 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 7b8046e..803e788 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1092,6 +1092,23 @@
   return SDOperand(N, 0);
 }
 
+SDOperand SelectionDAG::getVecLoad(unsigned Count, MVT::ValueType EVT,
+                                   SDOperand Chain, SDOperand Ptr,
+                                   SDOperand SV) {
+  SDNode *&N = Loads[std::make_pair(Ptr, std::make_pair(Chain, EVT))];
+  if (N) return SDOperand(N, 0);
+  std::vector<SDOperand> Ops;
+  Ops.reserve(5);
+  Ops.push_back(Chain);
+  Ops.push_back(Ptr);
+  Ops.push_back(getConstant(Count, MVT::i32));
+  Ops.push_back(getValueType(EVT));
+  Ops.push_back(SV);
+  std::vector<MVT::ValueType> VTs;
+  VTs.reserve(2);
+  VTs.push_back(EVT); VTs.push_back(MVT::Other);  // Add token chain.
+  return getNode(ISD::VLOAD, VTs, Ops);
+}
 
 SDOperand SelectionDAG::getExtLoad(unsigned Opcode, MVT::ValueType VT,
                                    SDOperand Chain, SDOperand Ptr, SDOperand SV,
@@ -1677,6 +1694,9 @@
   case ISD::FMUL:   return "fmul";
   case ISD::FDIV:   return "fdiv";
   case ISD::FREM:   return "frem";
+  case ISD::VADD:   return "vadd";
+  case ISD::VSUB:   return "vsub";
+  case ISD::VMUL:   return "vmul";
     
   case ISD::SETCC:       return "setcc";
   case ISD::SELECT:      return "select";
@@ -1717,6 +1737,7 @@
     // Other operators
   case ISD::LOAD:    return "load";
   case ISD::STORE:   return "store";
+  case ISD::VLOAD:   return "vload";
   case ISD::EXTLOAD:    return "extload";
   case ISD::SEXTLOAD:   return "sextload";
   case ISD::ZEXTLOAD:   return "zextload";