mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-14 17:34:41 +00:00
When checking for sret-demotion, it needs to use legal types. When using the return value of an sret-demoted call, it needs to use possibly illegal types that match the declared Type of the callee.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93667 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dbc130f592
commit
93ae407ec3
@ -800,18 +800,19 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) {
|
|||||||
SDNodeOrder, Chain, NULL);
|
SDNodeOrder, Chain, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the EVTs and ArgFlags collections that represent the return type
|
/// Get the EVTs and ArgFlags collections that represent the legalized return
|
||||||
/// of the given function. This does not require a DAG or a return value, and
|
/// type of the given function. This does not require a DAG or a return value,
|
||||||
/// is suitable for use before any DAGs for the function are constructed.
|
/// and is suitable for use before any DAGs for the function are constructed.
|
||||||
static void getReturnInfo(const Type* ReturnType,
|
static void getReturnInfo(const Type* ReturnType,
|
||||||
Attributes attr, SmallVectorImpl<EVT> &OutVTs,
|
Attributes attr, SmallVectorImpl<EVT> &OutVTs,
|
||||||
SmallVectorImpl<ISD::ArgFlagsTy> &OutFlags,
|
SmallVectorImpl<ISD::ArgFlagsTy> &OutFlags,
|
||||||
TargetLowering &TLI,
|
TargetLowering &TLI,
|
||||||
SmallVectorImpl<uint64_t> *Offsets = 0) {
|
SmallVectorImpl<uint64_t> *Offsets = 0) {
|
||||||
SmallVector<EVT, 4> ValueVTs;
|
SmallVector<EVT, 4> ValueVTs;
|
||||||
ComputeValueVTs(TLI, ReturnType, ValueVTs, Offsets);
|
ComputeValueVTs(TLI, ReturnType, ValueVTs);
|
||||||
unsigned NumValues = ValueVTs.size();
|
unsigned NumValues = ValueVTs.size();
|
||||||
if ( NumValues == 0 ) return;
|
if (NumValues == 0) return;
|
||||||
|
unsigned Offset = 0;
|
||||||
|
|
||||||
for (unsigned j = 0, f = NumValues; j != f; ++j) {
|
for (unsigned j = 0, f = NumValues; j != f; ++j) {
|
||||||
EVT VT = ValueVTs[j];
|
EVT VT = ValueVTs[j];
|
||||||
@ -834,6 +835,9 @@ static void getReturnInfo(const Type* ReturnType,
|
|||||||
|
|
||||||
unsigned NumParts = TLI.getNumRegisters(ReturnType->getContext(), VT);
|
unsigned NumParts = TLI.getNumRegisters(ReturnType->getContext(), VT);
|
||||||
EVT PartVT = TLI.getRegisterType(ReturnType->getContext(), VT);
|
EVT PartVT = TLI.getRegisterType(ReturnType->getContext(), VT);
|
||||||
|
unsigned PartSize = TLI.getTargetData()->getTypeAllocSize(
|
||||||
|
PartVT.getTypeForEVT(ReturnType->getContext()));
|
||||||
|
|
||||||
// 'inreg' on function refers to return value
|
// 'inreg' on function refers to return value
|
||||||
ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy();
|
ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy();
|
||||||
if (attr & Attribute::InReg)
|
if (attr & Attribute::InReg)
|
||||||
@ -848,6 +852,11 @@ static void getReturnInfo(const Type* ReturnType,
|
|||||||
for (unsigned i = 0; i < NumParts; ++i) {
|
for (unsigned i = 0; i < NumParts; ++i) {
|
||||||
OutVTs.push_back(PartVT);
|
OutVTs.push_back(PartVT);
|
||||||
OutFlags.push_back(Flags);
|
OutFlags.push_back(Flags);
|
||||||
|
if (Offsets)
|
||||||
|
{
|
||||||
|
Offsets->push_back(Offset);
|
||||||
|
Offset += PartSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5098,16 +5107,37 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
|
|||||||
SDValue Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
|
SDValue Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(),
|
||||||
MVT::Other, &Chains[0], NumValues);
|
MVT::Other, &Chains[0], NumValues);
|
||||||
PendingLoads.push_back(Chain);
|
PendingLoads.push_back(Chain);
|
||||||
|
|
||||||
|
// Collect the legal value parts into potentially illegal values
|
||||||
|
// that correspond to the original function's return values.
|
||||||
|
SmallVector<EVT, 4> RetTys;
|
||||||
|
RetTy = FTy->getReturnType();
|
||||||
|
ComputeValueVTs(TLI, RetTy, RetTys);
|
||||||
|
ISD::NodeType AssertOp = ISD::DELETED_NODE;
|
||||||
|
SmallVector<SDValue, 4> ReturnValues;
|
||||||
|
unsigned CurReg = 0;
|
||||||
|
for (unsigned I = 0, E = RetTys.size(); I != E; ++I) {
|
||||||
|
EVT VT = RetTys[I];
|
||||||
|
EVT RegisterVT = TLI.getRegisterType(RetTy->getContext(), VT);
|
||||||
|
unsigned NumRegs = TLI.getNumRegisters(RetTy->getContext(), VT);
|
||||||
|
|
||||||
|
SDValue ReturnValue =
|
||||||
|
getCopyFromParts(DAG, getCurDebugLoc(), SDNodeOrder, &Values[CurReg], NumRegs,
|
||||||
|
RegisterVT, VT, AssertOp);
|
||||||
|
ReturnValues.push_back(ReturnValue);
|
||||||
|
if (DisableScheduling)
|
||||||
|
DAG.AssignOrdering(ReturnValue.getNode(), SDNodeOrder);
|
||||||
|
CurReg += NumRegs;
|
||||||
|
}
|
||||||
|
SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(),
|
||||||
|
DAG.getVTList(&RetTys[0], RetTys.size()),
|
||||||
|
&ReturnValues[0], ReturnValues.size());
|
||||||
|
|
||||||
SDValue MV = DAG.getNode(ISD::MERGE_VALUES,
|
setValue(CS.getInstruction(), Res);
|
||||||
getCurDebugLoc(),
|
|
||||||
DAG.getVTList(&OutVTs[0], NumValues),
|
|
||||||
&Values[0], NumValues);
|
|
||||||
setValue(CS.getInstruction(), MV);
|
|
||||||
|
|
||||||
if (DisableScheduling) {
|
if (DisableScheduling) {
|
||||||
DAG.AssignOrdering(Chain.getNode(), SDNodeOrder);
|
DAG.AssignOrdering(Chain.getNode(), SDNodeOrder);
|
||||||
DAG.AssignOrdering(MV.getNode(), SDNodeOrder);
|
DAG.AssignOrdering(Res.getNode(), SDNodeOrder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
test/CodeGen/X86/bigstructret2.ll
Normal file
12
test/CodeGen/X86/bigstructret2.ll
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
; RUN: llc < %s -march=x86 -o %t
|
||||||
|
|
||||||
|
%0 = type { i64, i64 }
|
||||||
|
|
||||||
|
declare fastcc %0 @ReturnBigStruct() nounwind readnone
|
||||||
|
|
||||||
|
define void @test(%0* %p) {
|
||||||
|
%1 = call fastcc %0 @ReturnBigStruct()
|
||||||
|
store %0 %1, %0* %p
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user