diff options
author | Diana Picus <diana.picus@linaro.org> | 2017-05-29 08:19:19 +0000 |
---|---|---|
committer | Diana Picus <diana.picus@linaro.org> | 2017-05-29 08:19:19 +0000 |
commit | bf4aed2c38477758a7c5243f95675d55fe6d1633 (patch) | |
tree | 1970f9abb6565643ec1381c2afd15a7441a29ed2 /llvm/lib/Target/ARM/ARMCallLowering.cpp | |
parent | d9fb2842e75241b8404e5051b586b3f36d64f1e8 (diff) | |
download | bcm5719-llvm-bf4aed2c38477758a7c5243f95675d55fe6d1633.tar.gz bcm5719-llvm-bf4aed2c38477758a7c5243f95675d55fe6d1633.zip |
[ARM] GlobalISel: Support array returns
These are a bit rare in practice, but they don't require anything
special compared to array parameters, so support them as well.
llvm-svn: 304137
Diffstat (limited to 'llvm/lib/Target/ARM/ARMCallLowering.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMCallLowering.cpp | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/llvm/lib/Target/ARM/ARMCallLowering.cpp b/llvm/lib/Target/ARM/ARMCallLowering.cpp index 291d35d486a..53087adf973 100644 --- a/llvm/lib/Target/ARM/ARMCallLowering.cpp +++ b/llvm/lib/Target/ARM/ARMCallLowering.cpp @@ -214,8 +214,9 @@ bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder, SmallVector<ArgInfo, 4> SplitVTs; ArgInfo RetInfo(VReg, Val->getType()); setArgFlags(RetInfo, AttributeList::ReturnIndex, DL, F); - splitToValueTypes(RetInfo, SplitVTs, MF, - [&](unsigned Reg, uint64_t Offset) {}); + splitToValueTypes(RetInfo, SplitVTs, MF, [&](unsigned Reg, uint64_t Offset) { + MIRBuilder.buildExtract(Reg, VReg, Offset); + }); CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg()); @@ -476,13 +477,34 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, return false; ArgInfos.clear(); + SmallVector<uint64_t, 8> RegOffsets; + SmallVector<unsigned, 8> SplitRegs; splitToValueTypes(OrigRet, ArgInfos, MF, - [&](unsigned Reg, uint64_t Offset) {}); + [&](unsigned Reg, uint64_t Offset) { + RegOffsets.push_back(Offset); + SplitRegs.push_back(Reg); + }); auto RetAssignFn = TLI.CCAssignFnForReturn(CallConv, /*IsVarArg=*/false); CallReturnHandler RetHandler(MIRBuilder, MRI, MIB, RetAssignFn); if (!handleAssignments(MIRBuilder, ArgInfos, RetHandler)) return false; + + if (!RegOffsets.empty()) { + // We have split the value and allocated each individual piece, now build + // it up again. + LLT Ty = MRI.getType(OrigRet.Reg); + unsigned Dst = MRI.createGenericVirtualRegister(Ty); + MIRBuilder.buildUndef(Dst); + + for (unsigned i = 0; i < SplitRegs.size(); ++i) { + unsigned Tmp = MRI.createGenericVirtualRegister(Ty); + MIRBuilder.buildInsert(Tmp, Dst, SplitRegs[i], RegOffsets[i]); + Dst = Tmp; + } + + MIRBuilder.buildCopy(OrigRet.Reg, Dst); + } } // We now know the size of the stack - update the ADJCALLSTACKDOWN |