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