forked from OSchip/llvm-project
Add a parameter to getCopyToParts and getCopyFromParts to specify whether
endian swapping should be done, and update the code to use it. This fixes some register ordering issues on big-endian systems, such as PowerPC, introduced by the recent illegal by-val arguments changes. llvm-svn: 37921
This commit is contained in:
parent
fb0b269032
commit
d258e80583
|
@ -613,6 +613,195 @@ public:
|
|||
};
|
||||
} // 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 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
|
|||
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 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
|
|||
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 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
|
|||
}
|
||||
|
||||
|
||||
/// 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 @@ SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
|
|||
}
|
||||
|
||||
// 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 @@ SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
|
|||
/// 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 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||
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 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||
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 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||
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 @@ SDOperand SelectionDAGLowering::CopyValueToVirtualRegister(Value *V,
|
|||
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);
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue