Hi Evan,

I'm currently testing the attached patch, which seems to fix the
problems for PPC. It extends getCopyToParts and getCopyFromParts
to have an extra parameter to indicate when endian-swapping is
needed. I don't have access to a PPC test environment; I've included
a few trivial regression tests in this patch; I'll do some more
soon.

Copying to virtual registers is always done in little-endian order,
while copying to physical registers, arguments, or return values,
is done in target-endian order. I wonder if it would make sense to
change to using target-endian order for virtual registers as well?

Dan

On Tue, Jul 03, 2007 at 06:35:58PM -0700, Evan Cheng wrote:
> Hi Dan,
> 
> This patch is breaking llvm-gcc bootstrapping on PPC.
> 
> I am not sure what exactly wrong is it. But the old code has a check  
> for endianness while your new code doesn't. Can you check again if  
> you are taking endianness into consideration?
> 
> Thanks,
> 
> Evan
> 
> On Jul 2, 2007, at 9:18 AM, Dan Gohman wrote:
> 
> >Author: djg
> >Date: Mon Jul  2 11:18:06 2007
> >New Revision: 37843
> >
> >URL: http://llvm.org/viewvc/llvm-project?rev=37843&view=rev
> >Log:
> >Replace ExpandScalarFormalArgs and ExpandScalarCallArgs with the newly
> >refactored getCopyFromParts and getCopyToParts, which are more  
> >general.
> >This effectively adds support for lowering illegal by-val vector call
> >arguments.
> >
> >Modified:
> >    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> >
> >Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> >URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ 
> >SelectionDAG/SelectionDAGISel.cpp? 
> >rev=37843&r1=37842&r2=37843&view=diff
> >====================================================================== 
> >========
> >--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp  
> >(original)
> >+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon  
> >Jul  2 11:18:06 2007
> >@@ -2861,7 +2861,7 @@
> >   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)
> >+      for (unsigned i = 0; i != NumParts; ++i)
> >         Parts[i] = DAG.getNode(ISD::EXTRACT_ELEMENT, PartVT, Val,
> >                                DAG.getConstant(i, MVT::i32));
> >       return;
> >@@ -2950,7 +2950,7 @@
> >   // Copy the legal parts from the registers.
> >   unsigned NumParts = Regs.size();
> >   SmallVector<SDOperand, 8> Parts(NumParts);
> >-  for (unsigned i = 0; i < NumParts; ++i) {
> >+  for (unsigned i = 0; i != NumParts; ++i) {
> >     SDOperand Part = Flag ?
> >                      DAG.getCopyFromReg(Chain, Regs[i], RegVT,  
> >*Flag) :
> >                      DAG.getCopyFromReg(Chain, Regs[i], RegVT);
> >@@ -2981,7 +2981,7 @@
> >   getCopyToParts(DAG, Val, &Parts[0], NumParts, RegVT);
> >
> >   // Copy the parts into the registers.
> >-  for (unsigned i = 0; i < NumParts; ++i) {
> >+  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]);
> >@@ -3746,32 +3746,6 @@
> >                           DAG.getSrcValue(I.getOperand(2))));
> > }
> >
> >-/// ExpandScalarFormalArgs - Recursively expand the  
> >formal_argument node, either
> >-/// bit_convert it or join a pair of them with a BUILD_PAIR when  
> >appropriate.
> >-static SDOperand ExpandScalarFormalArgs(MVT::ValueType VT, SDNode  
> >*Arg,
> >-                                        unsigned &i, SelectionDAG  
> >&DAG,
> >-                                        TargetLowering &TLI) {
> >-  if (TLI.getTypeAction(VT) != TargetLowering::Expand)
> >-    return SDOperand(Arg, i++);
> >-
> >-  MVT::ValueType EVT = TLI.getTypeToTransformTo(VT);
> >-  unsigned NumVals = MVT::getSizeInBits(VT) / MVT::getSizeInBits 
> >(EVT);
> >-  if (NumVals == 1) {
> >-    return DAG.getNode(ISD::BIT_CONVERT, VT,
> >-                       ExpandScalarFormalArgs(EVT, Arg, i, DAG,  
> >TLI));
> >-  } else if (NumVals == 2) {
> >-    SDOperand Lo = ExpandScalarFormalArgs(EVT, Arg, i, DAG, TLI);
> >-    SDOperand Hi = ExpandScalarFormalArgs(EVT, Arg, i, DAG, TLI);
> >-    if (!TLI.isLittleEndian())
> >-      std::swap(Lo, Hi);
> >-    return DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi);
> >-  } else {
> >-    // Value scalarized into many values.  Unimp for now.
> >-    assert(0 && "Cannot expand i64 -> i16 yet!");
> >-  }
> >-  return SDOperand();
> >-}
> >-
> > /// TargetLowering::LowerArguments - This is the default  
> >LowerArguments
> > /// implementation, which just inserts a FORMAL_ARGUMENTS node.   
> >FIXME: When all
> > /// targets are migrated to using FORMAL_ARGUMENTS, this hook  
> >should be
> >@@ -3842,8 +3816,8 @@
> >   SDNode *Result = DAG.getNode(ISD::FORMAL_ARGUMENTS,
> >                                DAG.getNodeValueTypes(RetVals),  
> >RetVals.size(),
> >                                &Ops[0], Ops.size()).Val;
> >-
> >-  DAG.setRoot(SDOperand(Result, Result->getNumValues()-1));
> >+  unsigned NumArgRegs = Result->getNumValues() - 1;
> >+  DAG.setRoot(SDOperand(Result, NumArgRegs));
> >
> >   // Set up the return result vector.
> >   Ops.clear();
> >@@ -3875,79 +3849,22 @@
> >       Ops.push_back(Op);
> >       break;
> >     }
> >-    case Expand:
> >-      if (!MVT::isVector(VT)) {
> >-        // If this is a large integer or a floating point node  
> >that needs to be
> >-        // expanded, it needs to be reassembled from small  
> >integers.  Figure out
> >-        // what the source elt type is and how many small integers  
> >it is.
> >-        Ops.push_back(ExpandScalarFormalArgs(VT, Result, i, DAG,  
> >*this));
> >-      } else {
> >-        // Otherwise, this is a vector type.  We only support  
> >legal vectors
> >-        // right now.
> >-        const VectorType *PTy = cast<VectorType>(I->getType());
> >-        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)) {
> >-          SDOperand N = SDOperand(Result, i++);
> >-          // Handle copies from vectors to registers.
> >-          N = DAG.getNode(ISD::BIT_CONVERT, TVT, N);
> >-          Ops.push_back(N);
> >-        } else {
> >-          assert(0 && "Don't support illegal by-val vector  
> >arguments yet!");
> >-          abort();
> >-        }
> >-      }
> >+    case Expand: {
> >+      MVT::ValueType PartVT = getRegisterType(VT);
> >+      unsigned NumParts = getNumRegisters(VT);
> >+      SmallVector<SDOperand, 4> Parts(NumParts);
> >+      for (unsigned j = 0; j != NumParts; ++j)
> >+        Parts[j] = SDOperand(Result, i++);
> >+      Ops.push_back(getCopyFromParts(DAG, &Parts[0], NumParts,  
> >PartVT, VT));
> >       break;
> >     }
> >+    }
> >   }
> >+  assert(i == NumArgRegs && "Argument register count mismatch!");
> >   return Ops;
> > }
> >
> >
> >-/// ExpandScalarCallArgs - Recursively expand call argument node by
> >-/// bit_converting it or extract a pair of elements from the  
> >larger  node.
> >-static void ExpandScalarCallArgs(MVT::ValueType VT, SDOperand Arg,
> >-                                 unsigned Flags,
> >-                                 SmallVector<SDOperand, 32> &Ops,
> >-                                 SelectionDAG &DAG,
> >-                                 TargetLowering &TLI,
> >-                                 bool isFirst = true) {
> >-
> >-  if (TLI.getTypeAction(VT) != TargetLowering::Expand) {
> >-    // if it isn't first piece, alignment must be 1
> >-    if (!isFirst)
> >-      Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) |
> >-        (1 << ISD::ParamFlags::OrigAlignmentOffs);
> >-    Ops.push_back(Arg);
> >-    Ops.push_back(DAG.getConstant(Flags, MVT::i32));
> >-    return;
> >-  }
> >-
> >-  MVT::ValueType EVT = TLI.getTypeToTransformTo(VT);
> >-  unsigned NumVals = MVT::getSizeInBits(VT) / MVT::getSizeInBits 
> >(EVT);
> >-  if (NumVals == 1) {
> >-    Arg = DAG.getNode(ISD::BIT_CONVERT, EVT, Arg);
> >-    ExpandScalarCallArgs(EVT, Arg, Flags, Ops, DAG, TLI, isFirst);
> >-  } else if (NumVals == 2) {
> >-    SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, EVT, Arg,
> >-                               DAG.getConstant(0, TLI.getPointerTy 
> >()));
> >-    SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, EVT, Arg,
> >-                               DAG.getConstant(1, TLI.getPointerTy 
> >()));
> >-    if (!TLI.isLittleEndian())
> >-      std::swap(Lo, Hi);
> >-    ExpandScalarCallArgs(EVT, Lo, Flags, Ops, DAG, TLI, isFirst);
> >-    ExpandScalarCallArgs(EVT, Hi, Flags, Ops, DAG, TLI, false);
> >-  } else {
> >-    // Value scalarized into many values.  Unimp for now.
> >-    assert(0 && "Cannot expand i64 -> i16 yet!");
> >-  }
> >-}
> >-
> > /// TargetLowering::LowerCallTo - This is the default LowerCallTo
> > /// implementation, which just inserts an ISD::CALL node, which is  
> >later custom
> > /// lowered by the target to something concrete.  FIXME: When all  
> >targets are
> >@@ -4014,35 +3931,24 @@
> >       Ops.push_back(Op);
> >       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 down  
> >into small
> >-        // integers.  Figure out what the source elt type is and  
> >how many small
> >-        // integers it is.
> >-        ExpandScalarCallArgs(VT, Op, Flags, Ops, DAG, *this);
> >-      } else {
> >-        // Otherwise, this is a vector type.  We only support  
> >legal vectors
> >-        // right now.
> >-        const VectorType *PTy = cast<VectorType>(Args[i].Ty);
> >-        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)) {
> >-          // Insert a BIT_CONVERT of the original type to the  
> >vector type.
> >-          Op = DAG.getNode(ISD::BIT_CONVERT, TVT, Op);
> >-          Ops.push_back(Op);
> >-          Ops.push_back(DAG.getConstant(Flags, MVT::i32));
> >-        } else {
> >-          assert(0 && "Don't support illegal by-val vector call  
> >args yet!");
> >-          abort();
> >-        }
> >+    case Expand: {
> >+      MVT::ValueType PartVT = getRegisterType(VT);
> >+      unsigned NumParts = getNumRegisters(VT);
> >+      SmallVector<SDOperand, 4> Parts(NumParts);
> >+      getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT);
> >+      for (unsigned i = 0; i != NumParts; ++i) {
> >+        // if it isn't first piece, alignment must be 1
> >+        unsigned MyFlags = Flags;
> >+        if (i != 0)
> >+          MyFlags = (MyFlags & (~ISD::ParamFlags::OrigAlignment)) |
> >+            (1 << ISD::ParamFlags::OrigAlignmentOffs);
> >+
> >+        Ops.push_back(Parts[i]);
> >+        Ops.push_back(DAG.getConstant(MyFlags, MVT::i32));
> >       }
> >       break;
> >     }
> >+    }
> >   }
> >
> >   // Figure out the result value types.
> >@@ -4360,7 +4266,7 @@
> >
> >   // Copy the value by legal parts into sequential virtual registers.
> >   getCopyToParts(DAG, Op, &Regs[0], NumRegs, RegisterVT);
> >-  for (unsigned i = 0; i < NumRegs; ++i)
> >+  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);
> > }
> >
> >
> >_______________________________________________
> >llvm-commits mailing list
> >llvm-commits@cs.uiuc.edu
> >http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 
Index: test/CodeGen/PowerPC/big-endian-actual-args.ll
===================================================================
--- test/CodeGen/PowerPC/big-endian-actual-args.ll      (revision 0)
+++ test/CodeGen/PowerPC/big-endian-actual-args.ll      (revision 0)
@@ -0,0 +1,7 @@
+; RUN: llvm-as < %s | llc -march=ppc32 | grep {addc 4, 4, 6}
+; RUN: llvm-as < %s | llc -march=ppc32 | grep {adde 3, 3, 5}
+
+define i64 @foo(i64 %x, i64 %y) {
+  %z = add i64 %x, %y
+  ret i64 %z
+}
Index: test/CodeGen/PowerPC/big-endian-formal-args.ll
===================================================================
--- test/CodeGen/PowerPC/big-endian-formal-args.ll      (revision 0)
+++ test/CodeGen/PowerPC/big-endian-formal-args.ll      (revision 0)
@@ -0,0 +1,11 @@
+; RUN: llvm-as < %s | llc -march=ppc32 | grep {li 6, 3}
+; RUN: llvm-as < %s | llc -march=ppc32 | grep {li 4, 2}
+; RUN: llvm-as < %s | llc -march=ppc32 | grep {li 3, 0}
+; RUN: llvm-as < %s | llc -march=ppc32 | grep {mr 5, 3}
+
+declare void @bar(i64 %x, i64 %y)
+
+define void @foo() {
+  call void @bar(i64 2, i64 3)
+  ret void
+}
Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp       (revision 37907)
+++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp       (working copy)
@@ -613,6 +613,195 @@
 };
 } // end namespace llvm
 
+
+/// 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,
+                                  bool EndianOrder,
+                                  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];
+      if (EndianOrder && !DAG.getTargetLoweringInfo().isLittleEndian())
+        std::swap(Val, Hi);
+      return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Val, Hi);
+    }
+
+    // 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::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, EndianOrder);
+  } 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, EndianOrder);
+  }
+  
+  // 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,
+                           bool EndianOrder) {
+  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));
+      if (EndianOrder && !DAG.getTargetLoweringInfo().isLittleEndian())
+        std::reverse(Parts, Parts + NumParts);
+      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;
+  }
+
+  // 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
+      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, EndianOrder);
+  } 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, 
EndianOrder);
+  }
+}
+
+
 SDOperand SelectionDAGLowering::getValue(const Value *V) {
   SDOperand &N = NodeMap[V];
   if (N.Val) return N;
@@ -713,8 +902,8 @@
     SDOperand RetOp = getValue(I.getOperand(i));
     
     // If this is an integer return value, we need to promote it ourselves to
-    // the full width of a register, since LegalizeOp will use ANY_EXTEND 
rather
-    // than sign/zero.
+    // the full width of a register, since getCopyToParts and Legalize will use
+    // ANY_EXTEND rather than sign/zero.
     // FIXME: C calling convention requires the return type to be promoted to
     // at least 32-bit. But this is not necessary for non-C calling 
conventions.
     if (MVT::isInteger(RetOp.getValueType()) && 
@@ -732,9 +921,19 @@
       if (Attrs && Attrs->paramHasAttr(0, ParamAttr::ZExt))
         ExtendKind = ISD::ZERO_EXTEND;
       RetOp = DAG.getNode(ExtendKind, TmpVT, RetOp);
+      NewValues.push_back(RetOp);
+      NewValues.push_back(DAG.getConstant(false, MVT::i32));
+    } else {
+      MVT::ValueType VT = RetOp.getValueType();
+      unsigned NumParts = TLI.getNumRegisters(VT);
+      MVT::ValueType PartVT = TLI.getRegisterType(VT);
+      SmallVector<SDOperand, 4> Parts(NumParts);
+      getCopyToParts(DAG, RetOp, &Parts[0], NumParts, PartVT, true);
+      for (unsigned i = 0; i < NumParts; ++i) {
+        NewValues.push_back(Parts[i]);
+        NewValues.push_back(DAG.getConstant(false, MVT::i32));
+      }
     }
-    NewValues.push_back(RetOp);
-    NewValues.push_back(DAG.getConstant(false, MVT::i32));
   }
   DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other,
                           &NewValues[0], NewValues.size()));
@@ -2779,197 +2978,14 @@
 }
 
 
-/// 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);
-    }
-
-    // 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::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;
-  }
-
-  // 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
-      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);
-  }
-}
-
-
 /// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from
 /// 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.
 /// If the Flag pointer is NULL, no flag is used.
 SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
                                         SDOperand &Chain, SDOperand 
*Flag)const{
-  // Get the list of registers, in the appropriate order.
+  // Get the list of registers.
   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();
@@ -2985,7 +3001,7 @@
   }
   
   // Assemble the legal parts into the final value.
-  return getCopyFromParts(DAG, &Parts[0], NumParts, RegVT, ValueVT);
+  return getCopyFromParts(DAG, &Parts[0], NumParts, RegVT, ValueVT, true);
 }
 
 /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
@@ -2994,15 +3010,13 @@
 /// If the Flag pointer is NULL, no flag is used.
 void RegsForValue::getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
                                  SDOperand &Chain, SDOperand *Flag) const {
-  // Get the list of registers, in the appropriate order.
+  // Get the list of registers.
   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);
+  getCopyToParts(DAG, Val, &Parts[0], NumParts, RegVT, true);
 
   // Copy the parts into the registers.
   for (unsigned i = 0; i != NumParts; ++i) {
@@ -3879,7 +3893,7 @@
       SmallVector<SDOperand, 4> Parts(NumParts);
       for (unsigned j = 0; j != NumParts; ++j)
         Parts[j] = SDOperand(Result, i++);
-      Ops.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT));
+      Ops.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT, 
true));
       break;
     }
     }
@@ -3951,7 +3965,7 @@
       MVT::ValueType PartVT = getRegisterType(VT);
       unsigned NumParts = getNumRegisters(VT);
       SmallVector<SDOperand, 4> Parts(NumParts);
-      getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT);
+      getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT, true);
       for (unsigned i = 0; i != NumParts; ++i) {
         // if it isn't first piece, alignment must be 1
         unsigned MyFlags = Flags;
@@ -3991,7 +4005,7 @@
     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);
+    Res = getCopyFromParts(DAG, &Results[0], NumRegs, RegisterVT, VT, false, 
AssertOp);
   }
 
   return std::make_pair(Res, Chain);
@@ -4281,7 +4295,7 @@
   SmallVector<SDOperand, 8> Chains(NumRegs);
 
   // Copy the value by legal parts into sequential virtual registers.
-  getCopyToParts(DAG, Op, &Regs[0], NumRegs, RegisterVT);
+  getCopyToParts(DAG, Op, &Regs[0], NumRegs, RegisterVT, false);
   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);
_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to