[llvm-commits] ARM problem

Dan Gohman djg at cray.com
Thu Jun 28 12:36:47 PDT 2007


Attached is my new patch for this bug. It's bigger than I had
originally planned, but it fixes the bug you reported, and it factors
out the copy-to-regs/copy-from-regs logic which was duplicated in
several places so that it's handled the same way in each place.

If this patch is not ok for any reason, I'll apply the simpler fix
to fix the regression for tonight's nightly test.

Dan

On Thu, Jun 28, 2007 at 02:06:43PM -0300, Lauro Ramos Venancio wrote:
> Hi Dan,
> 
> Do you already have the final fix for this problem? It caused a lot of
> fails on nightly test
> (http://llvm.org/nightlytest/test.php?machine=142&night=3088).
> 
> Lauro

-- 
Dan Gohman, Cray Inc.
-------------- next part --------------
Index: include/llvm/ADT/SmallVector.h
===================================================================
RCS file: /var/cvs/llvm/llvm/include/llvm/ADT/SmallVector.h,v
retrieving revision 1.30
diff -u -r1.30 SmallVector.h
--- include/llvm/ADT/SmallVector.h
+++ include/llvm/ADT/SmallVector.h
@@ -442,7 +442,7 @@
   SmallVector() : SmallVectorImpl<T>(NumTsAvailable) {
   }
   
-  SmallVector(unsigned Size, const T &Value)
+  SmallVector(unsigned Size, const T &Value = T())
     : SmallVectorImpl<T>(NumTsAvailable) {
     this->reserve(Size);
     while (Size--)
Index: include/llvm/CodeGen/SelectionDAGNodes.h
===================================================================
RCS file: /var/cvs/llvm/llvm/include/llvm/CodeGen/SelectionDAGNodes.h,v
retrieving revision 1.193
diff -u -r1.193 SelectionDAGNodes.h
--- include/llvm/CodeGen/SelectionDAGNodes.h
+++ include/llvm/CodeGen/SelectionDAGNodes.h
@@ -253,7 +253,7 @@
     /// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of
     /// vector type with the same length and element type, this produces a
     /// concatenated vector result value, with length equal to the sum of the
-    /// input vectors.
+    /// lengths of the input vectors.
     CONCAT_VECTORS,
     
     /// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an
Index: include/llvm/Target/TargetLowering.h
===================================================================
RCS file: /var/cvs/llvm/llvm/include/llvm/Target/TargetLowering.h,v
retrieving revision 1.133
diff -u -r1.133 TargetLowering.h
--- include/llvm/Target/TargetLowering.h
+++ include/llvm/Target/TargetLowering.h
@@ -212,12 +212,13 @@
   /// Similarly, MVT::v2i64 turns into 4 MVT::i32 values with both PPC and X86.
   ///
   /// This method returns the number of registers needed, and the VT for each
-  /// register.  It also returns the VT of the VectorType elements before they
-  /// are promoted/expanded.
+  /// register.  It also returns the VT and quantity of the intermediate values
+  /// before they are promoted/expanded.
   ///
   unsigned getVectorTypeBreakdown(MVT::ValueType VT, 
-                                  MVT::ValueType &ElementVT,
-                                  MVT::ValueType &LegalElementVT) const;
+                                  MVT::ValueType &IntermediateVT,
+                                  unsigned &NumIntermediates,
+                                  MVT::ValueType &RegisterVT) const;
   
   typedef std::vector<double>::const_iterator legal_fpimm_iterator;
   legal_fpimm_iterator legal_fpimm_begin() const {
@@ -360,6 +361,18 @@
     return VT == MVT::iPTR ? PointerTy : VT;
   }
 
+  /// getRegisterType - Return the type of registers that this ValueType will
+  /// eventually require.
+  MVT::ValueType getRegisterType(MVT::ValueType VT) const {
+    if (!MVT::isExtendedVT(VT))
+      return RegisterTypeForVT[VT];
+           
+    MVT::ValueType VT1, RegisterVT;
+    unsigned NumIntermediates;
+    (void)getVectorTypeBreakdown(VT, VT1, NumIntermediates, RegisterVT);
+    return RegisterVT;
+  }
+  
   /// getNumRegisters - Return the number of registers that this ValueType will
   /// eventually require.  This is one for any types promoted to live in larger
   /// registers, but may be more than one for types (like i64) that are split
@@ -369,7 +382,8 @@
       return NumRegistersForVT[VT];
            
     MVT::ValueType VT1, VT2;
-    return getVectorTypeBreakdown(VT, VT1, VT2);
+    unsigned NumIntermediates;
+    return getVectorTypeBreakdown(VT, VT1, NumIntermediates, VT2);
   }
   
   /// hasTargetDAGCombine - If true, the target has custom DAG combine
@@ -1034,6 +1048,7 @@
   /// each ValueType the target supports natively.
   TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE];
   unsigned char NumRegistersForVT[MVT::LAST_VALUETYPE];
+  MVT::ValueType RegisterTypeForVT[MVT::LAST_VALUETYPE];
 
   /// TransformToType - For any value types we are promoting or expanding, this
   /// contains the value type that we are changing to.  For Expanded types, this
Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp,v
retrieving revision 1.471
diff -u -r1.471 SelectionDAGISel.cpp
--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -90,7 +90,7 @@
   /// This is needed because values can be promoted into larger registers and
   /// expanded into multiple smaller registers than the value.
   struct VISIBILITY_HIDDEN RegsForValue {
-    /// Regs - This list hold the register (for legal and promoted values)
+    /// Regs - This list holds the register (for legal and promoted values)
     /// or register set (for expanded values) that the value should be assigned
     /// to.
     std::vector<unsigned> Regs;
@@ -118,14 +118,13 @@
     /// this value and returns the result as a ValueVT value.  This uses 
     /// Chain/Flag as the input and updates them for the output Chain/Flag.
     SDOperand getCopyFromRegs(SelectionDAG &DAG,
-                              SDOperand &Chain, SDOperand &Flag) const;
+                              SDOperand &Chain, SDOperand *Flag) const;
 
     /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
     /// specified value into the registers specified by this object.  This uses 
     /// Chain/Flag as the input and updates them for the output Chain/Flag.
     void getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
-                       SDOperand &Chain, SDOperand &Flag,
-                       MVT::ValueType PtrVT) const;
+                       SDOperand &Chain, SDOperand *Flag) const;
     
     /// AddInlineAsmOperands - Add this value to the specified inlineasm node
     /// operand list.  This adds the code marker and includes the number of 
@@ -306,15 +305,8 @@
 unsigned FunctionLoweringInfo::CreateRegForValue(const Value *V) {
   MVT::ValueType VT = TLI.getValueType(V->getType());
   
-  unsigned NumRegisters;
-  MVT::ValueType RegisterVT;
-  if (MVT::isVector(VT)) {
-    MVT::ValueType ElementVT;
-    NumRegisters = TLI.getVectorTypeBreakdown(VT, ElementVT, RegisterVT);
-  } else {
-    RegisterVT = TLI.getTypeToTransformTo(VT);
-    NumRegisters = TLI.getNumRegisters(VT);
-  }
+  unsigned NumRegisters = TLI.getNumRegisters(VT);
+  MVT::ValueType RegisterVT = TLI.getRegisterType(VT);
 
   unsigned R = MakeReg(RegisterVT);
   for (unsigned i = 1; i != NumRegisters; ++i)
@@ -695,79 +687,17 @@
   unsigned InReg = FuncInfo.ValueMap[V];
   assert(InReg && "Value not in map!");
   
-  // If this type is not legal, make it so now.
-  if (!MVT::isVector(VT)) {
-    if (TLI.getTypeAction(VT) == TargetLowering::Expand) {
-      // Source must be expanded.  This input value is actually coming from the
-      // register pair InReg and InReg+1.
-      MVT::ValueType DestVT = TLI.getTypeToExpandTo(VT);
-      unsigned NumVals = TLI.getNumRegisters(VT);
-      N = DAG.getCopyFromReg(DAG.getEntryNode(), InReg, DestVT);
-      if (NumVals == 1)
-        N = DAG.getNode(ISD::BIT_CONVERT, VT, N);
-      else {
-        assert(NumVals == 2 && "1 to 4 (and more) expansion not implemented!");
-        N = DAG.getNode(ISD::BUILD_PAIR, VT, N,
-                        DAG.getCopyFromReg(DAG.getEntryNode(), InReg+1, DestVT));
-      }
-    } else {
-      MVT::ValueType DestVT = TLI.getTypeToTransformTo(VT);
-      N = DAG.getCopyFromReg(DAG.getEntryNode(), InReg, DestVT);
-      if (TLI.getTypeAction(VT) == TargetLowering::Promote) // Promotion case
-        N = MVT::isFloatingPoint(VT)
-          ? DAG.getNode(ISD::FP_ROUND, VT, N)
-          : DAG.getNode(ISD::TRUNCATE, VT, N);
-    }
-  } else {
-    // Otherwise, if this is a vector, make it available as a vector
-    // here.
-    MVT::ValueType ElementVT, LegalElementVT;
-    unsigned NE = TLI.getVectorTypeBreakdown(VT, ElementVT,
-                                             LegalElementVT);
-
-    // Build a BUILD_VECTOR or CONCAT_VECTORS with the input registers.
-    SmallVector<SDOperand, 8> Ops;
-    if (ElementVT == LegalElementVT) {
-      // If the value types are legal, just BUILD the CopyFromReg nodes.
-      for (unsigned i = 0; i != NE; ++i)
-        Ops.push_back(DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, 
-                                         ElementVT));
-    } else if (ElementVT < LegalElementVT) {
-      // If the register was promoted, use TRUNCATE or FP_ROUND as appropriate.
-      for (unsigned i = 0; i != NE; ++i) {
-        SDOperand Op = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, 
-                                          LegalElementVT);
-        if (MVT::isFloatingPoint(ElementVT))
-          Op = DAG.getNode(ISD::FP_ROUND, ElementVT, Op);
-        else
-          Op = DAG.getNode(ISD::TRUNCATE, ElementVT, Op);
-        Ops.push_back(Op);
-      }
-    } else {
-      // If the register was expanded, use BUILD_PAIR.
-      assert((NE & 1) == 0 && "Must expand into a multiple of 2 elements!");
-      for (unsigned i = 0; i != NE; ++i) {
-        SDOperand Op0 = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, 
-                                           LegalElementVT);
-        SDOperand Op1 = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, 
-                                           LegalElementVT);
-        Ops.push_back(DAG.getNode(ISD::BUILD_PAIR, ElementVT, Op0, Op1));
-      }
-    }
-    
-    if (MVT::isVector(ElementVT)) {
-      N = DAG.getNode(ISD::CONCAT_VECTORS,
-                      MVT::getVectorType(MVT::getVectorElementType(ElementVT),
-                                         NE * MVT::getVectorNumElements(ElementVT)),
-                      &Ops[0], Ops.size());
-    } else {
-      N = DAG.getNode(ISD::BUILD_VECTOR,
-                      MVT::getVectorType(ElementVT, NE),
-                      &Ops[0], Ops.size());
-    }
-  }
-  
-  return N;
+  MVT::ValueType RegisterVT = TLI.getRegisterType(VT);
+  unsigned NumRegs = TLI.getNumRegisters(VT);
+
+  std::vector<unsigned> Regs(NumRegs);
+  for (unsigned i = 0; i != NumRegs; ++i)
+    Regs[i] = InReg + i;
+
+  RegsForValue RFV(Regs, RegisterVT, VT);
+  SDOperand Chain = DAG.getEntryNode();
+
+  return RFV.getCopyFromRegs(DAG, Chain, NULL);
 }
 
 
@@ -2819,88 +2749,234 @@
 }
 
 
-SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
-                                        SDOperand &Chain, SDOperand &Flag)const{
-  SDOperand Val = DAG.getCopyFromReg(Chain, Regs[0], RegVT, Flag);
-  Chain = Val.getValue(1);
-  Flag  = Val.getValue(2);
-  
-  // If the result was expanded, copy from the top part.
-  if (Regs.size() > 1) {
-    assert(Regs.size() == 2 &&
-           "Cannot expand to more than 2 elts yet!");
-    SDOperand Hi = DAG.getCopyFromReg(Chain, Regs[1], RegVT, Flag);
-    Chain = Hi.getValue(1);
-    Flag  = Hi.getValue(2);
-    if (DAG.getTargetLoweringInfo().isLittleEndian())
+/// getCopyFromParts - Create a value that contains the
+/// specified legal parts combined into the value they represent.
+static SDOperand getCopyFromParts(SelectionDAG &DAG,
+                                  const SDOperand *Parts,
+                                  unsigned NumParts,
+                                  MVT::ValueType PartVT,
+                                  MVT::ValueType ValueVT,
+                                  ISD::NodeType AssertOp = ISD::DELETED_NODE) {
+  if (!MVT::isVector(ValueVT) || NumParts == 1) {
+    SDOperand Val = Parts[0];
+
+    // If the value was expanded, copy from the top part.
+    if (NumParts > 1) {
+      assert(NumParts == 2 &&
+             "Cannot expand to more than 2 elts yet!");
+      SDOperand Hi = Parts[1];
       return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Val, Hi);
-    else
-      return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Hi, Val);
-  }
+    }
 
-  // Otherwise, if the return value was promoted or extended, truncate it to the
-  // appropriate type.
-  if (RegVT == ValueVT)
-    return Val;
+    // Otherwise, if the value was promoted or extended, truncate it to the
+    // appropriate type.
+    if (PartVT == ValueVT)
+      return Val;
+  
+    if (MVT::isVector(PartVT)) {
+      assert(MVT::isVector(ValueVT) && "Unknown vector conversion!");
+      return DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+    }
+  
+    if (MVT::isInteger(PartVT) &&
+        MVT::isInteger(ValueVT)) {
+      if (ValueVT < PartVT) {
+        // For a truncate, see if we have any information to
+        // indicate whether the truncated bits will always be
+        // zero or sign-extension.
+        if (AssertOp != ISD::DELETED_NODE)
+          Val = DAG.getNode(AssertOp, PartVT, Val,
+                            DAG.getValueType(ValueVT));
+        return DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
+      } else {
+        return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
+      }
+    }
   
-  if (MVT::isVector(RegVT)) {
-    assert(MVT::isVector(ValueVT) && "Unknown vector conversion!");
-    return DAG.getNode(ISD::BIT_CONVERT, RegVT, Val);
+    if (MVT::isFloatingPoint(PartVT) &&
+        MVT::isFloatingPoint(ValueVT))
+      return DAG.getNode(ISD::FP_ROUND, ValueVT, Val);
+
+    if (MVT::getSizeInBits(PartVT) == 
+        MVT::getSizeInBits(ValueVT))
+      return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
+
+    assert(0 && "Unknown mismatch!");
+  }
+
+  // Handle a multi-element vector.
+  MVT::ValueType IntermediateVT, RegisterVT;
+  unsigned NumIntermediates;
+  unsigned NumRegs =
+    DAG.getTargetLoweringInfo()
+      .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
+                              RegisterVT);
+
+  assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
+  assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
+  assert(RegisterVT == Parts[0].getValueType() &&
+         "Part type doesn't match part!");
+
+  // Assemble the parts into intermediate operands.
+  SmallVector<SDOperand, 8> Ops(NumIntermediates);
+  if (NumIntermediates == NumParts) {
+    // If the register was not expanded, truncate or copy the value,
+    // as appropriate.
+    for (unsigned i = 0; i != NumParts; ++i)
+      Ops[i] = getCopyFromParts(DAG, &Parts[i], 1, PartVT, IntermediateVT);
+  } else if (NumParts > 0) {
+    // If the intermediate type was expanded, build the intermediate operands
+    // from the parts.
+    assert(NumIntermediates % NumParts == 0 &&
+           "Must expand into a divisible number of parts!");
+    unsigned Factor = NumIntermediates / NumParts;
+    for (unsigned i = 0; i != NumIntermediates; ++i)
+      Ops[i] = getCopyFromParts(DAG, &Parts[i * Factor], Factor,
+                                PartVT, IntermediateVT);
+  }
+  
+  // Build a vector with BUILD_VECTOR or CONCAT_VECTORS from the intermediate
+  // operands.
+  return DAG.getNode(MVT::isVector(IntermediateVT) ?
+                       ISD::CONCAT_VECTORS :
+                       ISD::BUILD_VECTOR,
+                     ValueVT, &Ops[0], NumParts);
+}
+
+/// getCopyToParts - Create a series of nodes that contain the
+/// specified value split into legal parts.
+static void getCopyToParts(SelectionDAG &DAG,
+                           SDOperand Val,
+                           SDOperand *Parts,
+                           unsigned NumParts,
+                           MVT::ValueType PartVT) {
+  MVT::ValueType ValueVT = Val.getValueType();
+
+  if (!MVT::isVector(ValueVT) || NumParts == 1) {
+    // If the value was expanded, copy from the parts.
+    if (NumParts > 1) {
+      for (unsigned i = 0; i < NumParts; ++i)
+        Parts[i] = DAG.getNode(ISD::EXTRACT_ELEMENT, PartVT, Val,
+                               DAG.getConstant(i, MVT::i32));
+      return;
+    }
+
+    // If there is a single part and the types differ, this must be
+    // a promotion.
+    if (PartVT != ValueVT) {
+      if (MVT::isVector(PartVT)) {
+        assert(MVT::isVector(ValueVT) &&
+               "Not a vector-vector cast?");
+        Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+      } else if (MVT::isInteger(PartVT) && MVT::isInteger(ValueVT)) {
+        if (PartVT < ValueVT)
+          Val = DAG.getNode(ISD::TRUNCATE, PartVT, Val);
+        else
+          Val = DAG.getNode(ISD::ANY_EXTEND, PartVT, Val);
+      } else if (MVT::isFloatingPoint(PartVT) &&
+                 MVT::isFloatingPoint(ValueVT)) {
+        Val = DAG.getNode(ISD::FP_EXTEND, PartVT, Val);
+      } else if (MVT::getSizeInBits(PartVT) == 
+                 MVT::getSizeInBits(ValueVT)) {
+        Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+      } else {
+        assert(0 && "Unknown mismatch!");
+      }
+    }
+    Parts[0] = Val;
+    return;
   }
-  
-  if (MVT::isInteger(RegVT)) {
-    if (ValueVT < RegVT)
-      return DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
+
+  // Handle a multi-element vector.
+  MVT::ValueType IntermediateVT, RegisterVT;
+  unsigned NumIntermediates;
+  unsigned NumRegs =
+    DAG.getTargetLoweringInfo()
+      .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
+                              RegisterVT);
+  unsigned NumElements = MVT::getVectorNumElements(ValueVT);
+
+  assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
+  assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
+
+  // Split the vector into intermediate operands.
+  SmallVector<SDOperand, 8> Ops(NumIntermediates);
+  for (unsigned i = 0; i != NumIntermediates; ++i)
+    if (MVT::isVector(IntermediateVT))
+      Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR,
+                           IntermediateVT, Val,
+                           DAG.getConstant(i * (NumElements / NumIntermediates),
+                                           MVT::i32));
     else
-      return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
+      Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
+                           IntermediateVT, Val, 
+                           DAG.getConstant(i, MVT::i32));
+
+  // Split the intermediate operands into legal parts.
+  if (NumParts == NumIntermediates) {
+    // If the register was not expanded, promote or copy the value,
+    // as appropriate.
+    for (unsigned i = 0; i != NumParts; ++i)
+      getCopyToParts(DAG, Ops[i], &Parts[i], 1, PartVT);
+  } else if (NumParts > 0) {
+    // If the intermediate type was expanded, split each the value into
+    // legal parts.
+    assert(NumParts % NumIntermediates == 0 &&
+           "Must expand into a divisible number of parts!");
+    unsigned Factor = NumParts / NumIntermediates;
+    for (unsigned i = 0; i != NumIntermediates; ++i)
+      getCopyToParts(DAG, Ops[i], &Parts[i * Factor], Factor, PartVT);
+  }
+}
+
+
+SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
+                                        SDOperand &Chain, SDOperand *Flag)const{
+  // Get the list of registers, in the appropriate order.
+  std::vector<unsigned> R(Regs);
+  if (!DAG.getTargetLoweringInfo().isLittleEndian())
+    std::reverse(R.begin(), R.end());
+
+  // Copy the legal parts from the registers.
+  unsigned NumParts = Regs.size();
+  SmallVector<SDOperand, 8> Parts(NumParts);
+  for (unsigned i = 0; i < NumParts; ++i) {
+    SDOperand Part = Flag ?
+                     DAG.getCopyFromReg(Chain, Regs[i], RegVT, *Flag) :
+                     DAG.getCopyFromReg(Chain, Regs[i], RegVT);
+    Chain = Part.getValue(1);
+    if (Flag)
+      *Flag = Part.getValue(2);
+    Parts[i] = Part;
   }
   
-  assert(MVT::isFloatingPoint(RegVT) && MVT::isFloatingPoint(ValueVT));
-  return DAG.getNode(ISD::FP_ROUND, ValueVT, Val);
+  // Assemble the legal parts into the final value.
+  return getCopyFromParts(DAG, &Parts[0], NumParts, RegVT, ValueVT);
 }
 
 /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
 /// specified value into the registers specified by this object.  This uses 
 /// Chain/Flag as the input and updates them for the output Chain/Flag.
 void RegsForValue::getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
-                                 SDOperand &Chain, SDOperand &Flag,
-                                 MVT::ValueType PtrVT) const {
-  if (Regs.size() == 1) {
-    // If there is a single register and the types differ, this must be
-    // a promotion.
-    if (RegVT != ValueVT) {
-      if (MVT::isVector(RegVT)) {
-        assert(MVT::isVector(Val.getValueType()) &&
-               "Not a vector-vector cast?");
-        Val = DAG.getNode(ISD::BIT_CONVERT, RegVT, Val);
-      } else if (MVT::isInteger(RegVT) && MVT::isInteger(Val.getValueType())) {
-        if (RegVT < ValueVT)
-          Val = DAG.getNode(ISD::TRUNCATE, RegVT, Val);
-        else
-          Val = DAG.getNode(ISD::ANY_EXTEND, RegVT, Val);
-      } else if (MVT::isFloatingPoint(RegVT) &&
-                 MVT::isFloatingPoint(Val.getValueType())) {
-        Val = DAG.getNode(ISD::FP_EXTEND, RegVT, Val);
-      } else if (MVT::getSizeInBits(RegVT) == 
-                 MVT::getSizeInBits(Val.getValueType())) {
-        Val = DAG.getNode(ISD::BIT_CONVERT, RegVT, Val);
-      } else {
-        assert(0 && "Unknown mismatch!");
-      }
-    }
-    Chain = DAG.getCopyToReg(Chain, Regs[0], Val, Flag);
-    Flag = Chain.getValue(1);
-  } else {
-    std::vector<unsigned> R(Regs);
-    if (!DAG.getTargetLoweringInfo().isLittleEndian())
-      std::reverse(R.begin(), R.end());
-    
-    for (unsigned i = 0, e = R.size(); i != e; ++i) {
-      SDOperand Part = DAG.getNode(ISD::EXTRACT_ELEMENT, RegVT, Val, 
-                                   DAG.getConstant(i, PtrVT));
-      Chain = DAG.getCopyToReg(Chain, R[i], Part, Flag);
-      Flag = Chain.getValue(1);
-    }
+                                 SDOperand &Chain, SDOperand *Flag) const {
+  // Get the list of registers, in the appropriate order.
+  std::vector<unsigned> R(Regs);
+  if (!DAG.getTargetLoweringInfo().isLittleEndian())
+    std::reverse(R.begin(), R.end());
+
+  // Get the list of the values's legal parts.
+  unsigned NumParts = Regs.size();
+  SmallVector<SDOperand, 8> Parts(NumParts);
+  getCopyToParts(DAG, Val, &Parts[0], NumParts, RegVT);
+
+  // Copy the parts into the registers.
+  for (unsigned i = 0; i < NumParts; ++i) {
+    SDOperand Part = Flag ?
+                     DAG.getCopyToReg(Chain, R[i], Parts[i], *Flag) :
+                     DAG.getCopyToReg(Chain, R[i], Parts[i]);
+    Chain = Part.getValue(0);
+    if (Flag)
+      *Flag = Part.getValue(1);
   }
 }
 
@@ -3456,8 +3532,7 @@
           }
         
           // Use the produced MatchedRegs object to 
-          MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, Flag,
-                                    TLI.getPointerTy());
+          MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag);
           MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands);
           break;
         } else {
@@ -3508,8 +3583,7 @@
       assert(!OpInfo.AssignedRegs.Regs.empty() &&
              "Couldn't allocate input reg!");
 
-      OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, Chain, Flag, 
-                                        TLI.getPointerTy());
+      OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag);
       
       OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/, DAG,
                                                AsmNodeOperands);
@@ -3538,7 +3612,7 @@
   // If this asm returns a register value, copy the result from that register
   // and set it as the value of the call.
   if (!RetValRegs.Regs.empty()) {
-    SDOperand Val = RetValRegs.getCopyFromRegs(DAG, Chain, Flag);
+    SDOperand Val = RetValRegs.getCopyFromRegs(DAG, Chain, &Flag);
     
     // If the result of the inline asm is a vector, it may have the wrong
     // width/num elts.  Make sure to convert it to the right type with
@@ -3560,7 +3634,7 @@
   for (unsigned i = 0, e = IndirectStoresToEmit.size(); i != e; ++i) {
     RegsForValue &OutRegs = IndirectStoresToEmit[i].first;
     Value *Ptr = IndirectStoresToEmit[i].second;
-    SDOperand OutVal = OutRegs.getCopyFromRegs(DAG, Chain, Flag);
+    SDOperand OutVal = OutRegs.getCopyFromRegs(DAG, Chain, &Flag);
     StoresToEmit.push_back(std::make_pair(OutVal, Ptr));
   }
   
@@ -3733,40 +3807,22 @@
       RetVals.push_back(getTypeToTransformTo(VT));
       Ops.push_back(DAG.getConstant(Flags, MVT::i32));
       break;
-    case Expand:
-      if (!MVT::isVector(VT)) {
-        // If this is a large integer, it needs to be broken up into small
-        // integers.  Figure out what the destination type is and how many small
-        // integers it turns into.
-        MVT::ValueType NVT = getTypeToExpandTo(VT);
-        unsigned NumVals = getNumRegisters(VT);
-        for (unsigned i = 0; i != NumVals; ++i) {
-          RetVals.push_back(NVT);
-          // if it isn't first piece, alignment must be 1
-          if (i > 0)
-            Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) |
-              (1 << ISD::ParamFlags::OrigAlignmentOffs);
-          Ops.push_back(DAG.getConstant(Flags, MVT::i32));
-        }
-      } else {
-        // Otherwise, this is a vector type.  We only support legal vectors
-        // right now.
-        unsigned NumElems = cast<VectorType>(I->getType())->getNumElements();
-        const Type *EltTy = cast<VectorType>(I->getType())->getElementType();
-
-        // Figure out if there is a Packed type corresponding to this Vector
-        // type.  If so, convert to the vector type.
-        MVT::ValueType TVT =
-          MVT::getVectorType(getValueType(EltTy), NumElems);
-        if (TVT != MVT::Other && isTypeLegal(TVT)) {
-          RetVals.push_back(TVT);
-          Ops.push_back(DAG.getConstant(Flags, MVT::i32));
-        } else {
-          assert(0 && "Don't support illegal by-val vector arguments yet!");
-        }
+    case Expand: {
+      // If this is an illegal type, it needs to be broken up to fit into 
+      // registers.
+      MVT::ValueType RegisterVT = getRegisterType(VT);
+      unsigned NumRegs = getNumRegisters(VT);
+      for (unsigned i = 0; i != NumRegs; ++i) {
+        RetVals.push_back(RegisterVT);
+        // if it isn't first piece, alignment must be 1
+        if (i > 0)
+          Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) |
+            (1 << ISD::ParamFlags::OrigAlignmentOffs);
+        Ops.push_back(DAG.getConstant(Flags, MVT::i32));
       }
       break;
     }
+    }
   }
 
   RetVals.push_back(MVT::Other);
@@ -3979,108 +4035,33 @@
   }
   
   // Figure out the result value types.
-  SmallVector<MVT::ValueType, 4> RetTys;
-
-  if (RetTy != Type::VoidTy) {
-    MVT::ValueType VT = getValueType(RetTy);
-    switch (getTypeAction(VT)) {
-    default: assert(0 && "Unknown type action!");
-    case Legal:
-      RetTys.push_back(VT);
-      break;
-    case Promote:
-      RetTys.push_back(getTypeToTransformTo(VT));
-      break;
-    case Expand:
-      if (!MVT::isVector(VT)) {
-        // If this is a large integer, it needs to be reassembled from small
-        // integers.  Figure out what the source elt type is and how many small
-        // integers it is.
-        MVT::ValueType NVT = getTypeToExpandTo(VT);
-        unsigned NumVals = getNumRegisters(VT);
-        for (unsigned i = 0; i != NumVals; ++i)
-          RetTys.push_back(NVT);
-      } else {
-        // Otherwise, this is a vector type.  We only support legal vectors
-        // right now.
-        const VectorType *PTy = cast<VectorType>(RetTy);
-        unsigned NumElems = PTy->getNumElements();
-        const Type *EltTy = PTy->getElementType();
-        
-        // Figure out if there is a Packed type corresponding to this Vector
-        // type.  If so, convert to the vector type.
-        MVT::ValueType TVT =
-          MVT::getVectorType(getValueType(EltTy), NumElems);
-        if (TVT != MVT::Other && isTypeLegal(TVT)) {
-          RetTys.push_back(TVT);
-        } else {
-          assert(0 && "Don't support illegal by-val vector call results yet!");
-          abort();
-        }
-      }
-    }    
-  }
+  MVT::ValueType VT = getValueType(RetTy);
+  MVT::ValueType RegisterVT = getRegisterType(VT);
+  unsigned NumRegs = getNumRegisters(VT);
+  SmallVector<MVT::ValueType, 4> RetTys(NumRegs);
+  for (unsigned i = 0; i != NumRegs; ++i)
+    RetTys[i] = RegisterVT;
   
   RetTys.push_back(MVT::Other);  // Always has a chain.
   
-  // Finally, create the CALL node.
+  // Create the CALL node.
   SDOperand Res = DAG.getNode(ISD::CALL,
-                              DAG.getVTList(&RetTys[0], RetTys.size()),
+                              DAG.getVTList(&RetTys[0], NumRegs + 1),
                               &Ops[0], Ops.size());
-  
-  // This returns a pair of operands.  The first element is the
-  // return value for the function (if RetTy is not VoidTy).  The second
-  // element is the outgoing token chain.
-  SDOperand ResVal;
-  if (RetTys.size() != 1) {
-    MVT::ValueType VT = getValueType(RetTy);
-    if (RetTys.size() == 2) {
-      ResVal = Res;
-      
-      // If this value was promoted, truncate it down.
-      if (ResVal.getValueType() != VT) {
-        if (MVT::isVector(VT)) {
-          // Insert a BIT_CONVERT to convert from the packed result type to the
-          // new vector type.
-          unsigned NumElems = cast<VectorType>(RetTy)->getNumElements();
-          const Type *EltTy = cast<VectorType>(RetTy)->getElementType();
-          
-          // Figure out if there is a Packed type corresponding to this Vector
-          // type.  If so, convert to the vector type.
-          MVT::ValueType TVT =
-            MVT::getVectorType(getValueType(EltTy),NumElems);
-          if (TVT != MVT::Other && isTypeLegal(TVT)) {
-            // Insert a BIT_CONVERT of the FORMAL_ARGUMENTS to a
-            // "N x PTyElementVT" vector type.
-            ResVal = DAG.getNode(ISD::BIT_CONVERT, TVT, ResVal);
-          } else {
-            abort();
-          }
-        } else if (MVT::isInteger(VT)) {
-          unsigned AssertOp = ISD::AssertSext;
-          if (!RetTyIsSigned)
-            AssertOp = ISD::AssertZext;
-          ResVal = DAG.getNode(AssertOp, ResVal.getValueType(), ResVal, 
-                               DAG.getValueType(VT));
-          ResVal = DAG.getNode(ISD::TRUNCATE, VT, ResVal);
-        } else {
-          assert(MVT::isFloatingPoint(VT));
-          if (getTypeAction(VT) == Expand)
-            ResVal = DAG.getNode(ISD::BIT_CONVERT, VT, ResVal);
-          else
-            ResVal = DAG.getNode(ISD::FP_ROUND, VT, ResVal);
-        }
-      }
-    } else if (RetTys.size() == 3) {
-      ResVal = DAG.getNode(ISD::BUILD_PAIR, VT, 
-                           Res.getValue(0), Res.getValue(1));
-      
-    } else {
-      assert(0 && "Case not handled yet!");
-    }
+  SDOperand Chain = Res.getValue(NumRegs);
+
+  // Gather up the call result into a single value.
+  if (RetTy != Type::VoidTy) {
+    ISD::NodeType AssertOp = ISD::AssertSext;
+    if (!RetTyIsSigned)
+      AssertOp = ISD::AssertZext;
+    SmallVector<SDOperand, 4> Results(NumRegs);
+    for (unsigned i = 0; i != NumRegs; ++i)
+      Results[i] = Res.getValue(i);
+    Res = getCopyFromParts(DAG, &Results[0], NumRegs, RegisterVT, VT, AssertOp);
   }
-  
-  return std::make_pair(ResVal, Res.getValue(Res.Val->getNumValues()-1));
+
+  return std::make_pair(Res, Chain);
 }
 
 SDOperand TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
@@ -4360,75 +4341,17 @@
           cast<RegisterSDNode>(Op.getOperand(1))->getReg() != Reg) &&
          "Copy from a reg to the same reg!");
   
-  // If this type is not legal, we must make sure to not create an invalid
-  // register use.
   MVT::ValueType SrcVT = Op.getValueType();
-  MVT::ValueType DestVT = TLI.getTypeToTransformTo(SrcVT);
-  if (SrcVT == DestVT) {
-    return DAG.getCopyToReg(getRoot(), Reg, Op);
-  } else if (MVT::isVector(SrcVT)) {
-    // Handle copies from generic vectors to registers.
-    MVT::ValueType ElementVT, LegalElementVT;
-    unsigned NE = TLI.getVectorTypeBreakdown(SrcVT,
-                                             ElementVT, LegalElementVT);
-    uint64_t SrcVL = MVT::getVectorNumElements(SrcVT);
-    
-    // Loop over all of the elements of the resultant vector,
-    // EXTRACT_VECTOR_ELT'ing or EXTRACT_SUBVECTOR'ing them, converting them
-    // to LegalElementVT, then copying them into output registers.
-    SmallVector<SDOperand, 8> OutChains;
-    SDOperand Root = getRoot();
-    for (unsigned i = 0; i != NE; ++i) {
-      SDOperand Elt = MVT::isVector(ElementVT) ?
-        DAG.getNode(ISD::EXTRACT_SUBVECTOR, ElementVT,
-                    Op, DAG.getConstant(i * (SrcVL / NE), TLI.getPointerTy())) :
-        DAG.getNode(ISD::EXTRACT_VECTOR_ELT, ElementVT,
-                    Op, DAG.getConstant(i, TLI.getPointerTy()));
-      if (ElementVT == LegalElementVT) {
-        // Elements are legal.
-        OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Elt));
-      } else if (LegalElementVT > ElementVT) {
-        // Elements are promoted.
-        if (MVT::isFloatingPoint(LegalElementVT))
-          Elt = DAG.getNode(ISD::FP_EXTEND, LegalElementVT, Elt);
-        else
-          Elt = DAG.getNode(ISD::ANY_EXTEND, LegalElementVT, Elt);
-        OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Elt));
-      } else {
-        // Elements are expanded.
-        // The src value is expanded into multiple registers.
-        SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, LegalElementVT,
-                                   Elt, DAG.getConstant(0, TLI.getPointerTy()));
-        SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, LegalElementVT,
-                                   Elt, DAG.getConstant(1, TLI.getPointerTy()));
-        OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Lo));
-        OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Hi));
-      }
-    }
-    return DAG.getNode(ISD::TokenFactor, MVT::Other,
-                       &OutChains[0], OutChains.size());
-  } else if (TLI.getTypeAction(SrcVT) == TargetLowering::Promote) {
-    // The src value is promoted to the register.
-    if (MVT::isFloatingPoint(SrcVT))
-      Op = DAG.getNode(ISD::FP_EXTEND, DestVT, Op);
-    else
-      Op = DAG.getNode(ISD::ANY_EXTEND, DestVT, Op);
-    return DAG.getCopyToReg(getRoot(), Reg, Op);
-  } else  {
-    DestVT = TLI.getTypeToExpandTo(SrcVT);
-    unsigned NumVals = TLI.getNumRegisters(SrcVT);
-    if (NumVals == 1)
-      return DAG.getCopyToReg(getRoot(), Reg,
-                              DAG.getNode(ISD::BIT_CONVERT, DestVT, Op));
-    assert(NumVals == 2 && "1 to 4 (and more) expansion not implemented!");
-    // The src value is expanded into multiple registers.
-    SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DestVT,
-                               Op, DAG.getConstant(0, TLI.getPointerTy()));
-    SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DestVT,
-                               Op, DAG.getConstant(1, TLI.getPointerTy()));
-    Op = DAG.getCopyToReg(getRoot(), Reg, Lo);
-    return DAG.getCopyToReg(Op, Reg+1, Hi);
-  }
+  MVT::ValueType RegisterVT = TLI.getRegisterType(SrcVT);
+  unsigned NumRegs = TLI.getNumRegisters(SrcVT);
+  SmallVector<SDOperand, 8> Regs(NumRegs);
+  SmallVector<SDOperand, 8> Chains(NumRegs);
+
+  // Copy the value by legal parts into sequential virtual registers.
+  getCopyToParts(DAG, Op, &Regs[0], NumRegs, RegisterVT);
+  for (unsigned i = 0; i < NumRegs; ++i)
+    Chains[i] = DAG.getCopyToReg(getRoot(), Reg + i, Regs[i]);
+  return DAG.getNode(ISD::TokenFactor, MVT::Other, &Chains[0], NumRegs);
 }
 
 void SelectionDAGISel::
Index: lib/CodeGen/SelectionDAG/TargetLowering.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp,v
retrieving revision 1.123
diff -u -r1.123 TargetLowering.cpp
--- lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -165,58 +165,19 @@
 
 TargetLowering::~TargetLowering() {}
 
-/// setValueTypeAction - Set the action for a particular value type.  This
-/// assumes an action has not already been set for this value type.
-static void SetValueTypeAction(MVT::ValueType VT,
-                               TargetLowering::LegalizeAction Action,
-                               TargetLowering &TLI,
-                               MVT::ValueType *TransformToType,
-                        TargetLowering::ValueTypeActionImpl &ValueTypeActions) {
-  ValueTypeActions.setTypeAction(VT, Action);
-  if (Action == TargetLowering::Promote) {
-    MVT::ValueType PromoteTo;
-    if (VT == MVT::f32)
-      PromoteTo = MVT::f64;
-    else {
-      unsigned LargerReg = VT+1;
-      while (!TLI.isTypeLegal((MVT::ValueType)LargerReg)) {
-        ++LargerReg;
-        assert(MVT::isInteger((MVT::ValueType)LargerReg) &&
-               "Nothing to promote to??");
-      }
-      PromoteTo = (MVT::ValueType)LargerReg;
-    }
-
-    assert(MVT::isInteger(VT) == MVT::isInteger(PromoteTo) &&
-           MVT::isFloatingPoint(VT) == MVT::isFloatingPoint(PromoteTo) &&
-           "Can only promote from int->int or fp->fp!");
-    assert(VT < PromoteTo && "Must promote to a larger type!");
-    TransformToType[VT] = PromoteTo;
-  } else if (Action == TargetLowering::Expand) {
-    // f32 and f64 is each expanded to corresponding integer type of same size.
-    if (VT == MVT::f32)
-      TransformToType[VT] = MVT::i32;
-    else if (VT == MVT::f64)
-      TransformToType[VT] = MVT::i64;
-    else {
-      assert((MVT::isVector(VT) || MVT::isInteger(VT)) && VT > MVT::i8 &&
-             "Cannot expand this type: target must support SOME integer reg!");
-      // Expand to the next smaller integer type!
-      TransformToType[VT] = (MVT::ValueType)(VT-1);
-    }
-  }
-}
-
-
 /// computeRegisterProperties - Once all of the register classes are added,
 /// this allows us to compute derived properties we expose.
 void TargetLowering::computeRegisterProperties() {
   assert(MVT::LAST_VALUETYPE <= 32 &&
          "Too many value types for ValueTypeActions to hold!");
 
-  // Everything defaults to one.
-  for (unsigned i = 0; i != MVT::LAST_VALUETYPE; ++i)
+  // Everything defaults to needing one register.
+  for (unsigned i = 0; i != MVT::LAST_VALUETYPE; ++i) {
     NumRegistersForVT[i] = 1;
+    RegisterTypeForVT[i] = TransformToType[i] = i;
+  }
+  // ...except isVoid, which doesn't need any registers.
+  NumRegistersForVT[MVT::isVoid] = 0;
 
   // Find the largest integer register class.
   unsigned LargestIntReg = MVT::i128;
@@ -225,57 +186,65 @@
 
   // Every integer value type larger than this largest register takes twice as
   // many registers to represent as the previous ValueType.
-  unsigned ExpandedReg = LargestIntReg; ++LargestIntReg;
-  for (++ExpandedReg; MVT::isInteger((MVT::ValueType)ExpandedReg);++ExpandedReg)
+  for (MVT::ValueType ExpandedReg = LargestIntReg + 1;
+       MVT::isInteger(ExpandedReg); ++ExpandedReg) {
     NumRegistersForVT[ExpandedReg] = 2*NumRegistersForVT[ExpandedReg-1];
+    RegisterTypeForVT[ExpandedReg] = LargestIntReg;
+    TransformToType[ExpandedReg] = ExpandedReg - 1;
+    ValueTypeActions.setTypeAction(ExpandedReg, Expand);
+  }
 
-  // Inspect all of the ValueType's possible, deciding how to process them.
-  for (unsigned IntReg = MVT::i1; IntReg <= MVT::i128; ++IntReg)
-    // If we are expanding this type, expand it!
-    if (getNumRegisters((MVT::ValueType)IntReg) != 1)
-      SetValueTypeAction((MVT::ValueType)IntReg, Expand, *this, TransformToType,
-                         ValueTypeActions);
-    else if (!isTypeLegal((MVT::ValueType)IntReg))
-      // Otherwise, if we don't have native support, we must promote to a
-      // larger type.
-      SetValueTypeAction((MVT::ValueType)IntReg, Promote, *this,
-                         TransformToType, ValueTypeActions);
-    else
-      TransformToType[(MVT::ValueType)IntReg] = (MVT::ValueType)IntReg;
-
-  // If the target does not have native f64 support, expand it to i64. We will
-  // be generating soft float library calls. If the target does not have native
-  // support for f32, promote it to f64 if it is legal. Otherwise, expand it to
-  // i32.
-  if (isTypeLegal(MVT::f64))
-    TransformToType[MVT::f64] = MVT::f64;  
-  else {
+  // Inspect all of the ValueType's smaller than the largest integer
+  // register to see which ones need promotion.
+  MVT::ValueType LegalIntReg = LargestIntReg;
+  for (MVT::ValueType IntReg = LargestIntReg - 1;
+       IntReg >= MVT::i1; --IntReg) {
+    if (isTypeLegal(IntReg)) {
+      LegalIntReg = IntReg;
+    } else {
+      RegisterTypeForVT[IntReg] = TransformToType[IntReg] = LegalIntReg;
+      ValueTypeActions.setTypeAction(IntReg, Promote);
+    }
+  }
+
+  // Decide how to handle f64. If the target does not have native f64 support,
+  // expand it to i64 and we will be generating soft float library calls.
+  if (!isTypeLegal(MVT::f64)) {
     NumRegistersForVT[MVT::f64] = NumRegistersForVT[MVT::i64];
-    SetValueTypeAction(MVT::f64, Expand, *this, TransformToType,
-                       ValueTypeActions);
+    RegisterTypeForVT[MVT::f64] = RegisterTypeForVT[MVT::i64];
+    TransformToType[MVT::f64] = MVT::i64;
+    ValueTypeActions.setTypeAction(MVT::f64, Expand);
   }
-  if (isTypeLegal(MVT::f32))
-    TransformToType[MVT::f32] = MVT::f32;
-  else if (isTypeLegal(MVT::f64))
-    SetValueTypeAction(MVT::f32, Promote, *this, TransformToType,
-                       ValueTypeActions);
-  else {
-    NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::i32];
-    SetValueTypeAction(MVT::f32, Expand, *this, TransformToType,
-                       ValueTypeActions);
-  }
-  
-  // Loop over all of the legal vector value types, specifying an identity type
-  // transformation.
-  for (unsigned i = MVT::FIRST_VECTOR_VALUETYPE;
+
+  // Decide how to handle f32. If the target does not have native support for
+  // f32, promote it to f64 if it is legal. Otherwise, expand it to i32.
+  if (!isTypeLegal(MVT::f32)) {
+    if (isTypeLegal(MVT::f64)) {
+      NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::f64];
+      RegisterTypeForVT[MVT::f32] = RegisterTypeForVT[MVT::f64];
+      TransformToType[MVT::f32] = MVT::f64;
+      ValueTypeActions.setTypeAction(MVT::f32, Promote);
+    } else {
+      NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::i32];
+      RegisterTypeForVT[MVT::f32] = RegisterTypeForVT[MVT::i32];
+      TransformToType[MVT::f32] = MVT::i32;
+      ValueTypeActions.setTypeAction(MVT::f32, Expand);
+    }
+  }
+  
+  // Loop over all of the vector value types to see which need transformations.
+  for (MVT::ValueType i = MVT::FIRST_VECTOR_VALUETYPE;
        i <= MVT::LAST_VECTOR_VALUETYPE; ++i) {
-    if (isTypeLegal((MVT::ValueType)i))
-      TransformToType[i] = (MVT::ValueType)i;
-    else {
-      MVT::ValueType VT1, VT2;
-      NumRegistersForVT[i] = getVectorTypeBreakdown(i, VT1, VT2);
-      SetValueTypeAction(i, Expand, *this, TransformToType,
-                         ValueTypeActions);
+    if (!isTypeLegal(i)) {
+      MVT::ValueType IntermediateVT, RegisterVT;
+      unsigned NumIntermediates;
+      NumRegistersForVT[i] =
+        getVectorTypeBreakdown(i,
+                               IntermediateVT, NumIntermediates,
+                               RegisterVT);
+      RegisterTypeForVT[i] = RegisterVT;
+      TransformToType[i] = MVT::Other; // this isn't actually used
+      ValueTypeActions.setTypeAction(i, Expand);
     }
   }
 }
@@ -290,12 +259,13 @@
 /// Similarly, MVT::v2i64 turns into 4 MVT::i32 values with both PPC and X86.
 ///
 /// This method returns the number of registers needed, and the VT for each
-/// register.  It also returns the VT of the VectorType elements before they
-/// are promoted/expanded.
+/// register.  It also returns the VT and quantity of the intermediate values
+/// before they are promoted/expanded.
 ///
 unsigned TargetLowering::getVectorTypeBreakdown(MVT::ValueType VT, 
-                                                MVT::ValueType &ElementVT,
-                                      MVT::ValueType &LegalElementVT) const {
+                                                MVT::ValueType &IntermediateVT,
+                                                unsigned &NumIntermediates,
+                                      MVT::ValueType &RegisterVT) const {
   // Figure out the right, legal destination reg to copy into.
   unsigned NumElts = MVT::getVectorNumElements(VT);
   MVT::ValueType EltTy = MVT::getVectorElementType(VT);
@@ -309,14 +279,16 @@
     NumElts >>= 1;
     NumVectorRegs <<= 1;
   }
+
+  NumIntermediates = NumVectorRegs;
   
   MVT::ValueType NewVT = MVT::getVectorType(EltTy, NumElts);
   if (!isTypeLegal(NewVT))
     NewVT = EltTy;
-  ElementVT = NewVT;
+  IntermediateVT = NewVT;
 
   MVT::ValueType DestVT = getTypeToTransformTo(NewVT);
-  LegalElementVT = DestVT;
+  RegisterVT = DestVT;
   if (DestVT < NewVT) {
     // Value is expanded, e.g. i64 -> i16.
     return NumVectorRegs*(MVT::getSizeInBits(NewVT)/MVT::getSizeInBits(DestVT));


More information about the llvm-commits mailing list