summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMCallLowering.cpp
diff options
context:
space:
mode:
authorDiana Picus <diana.picus@linaro.org>2017-05-29 08:19:19 +0000
committerDiana Picus <diana.picus@linaro.org>2017-05-29 08:19:19 +0000
commitbf4aed2c38477758a7c5243f95675d55fe6d1633 (patch)
tree1970f9abb6565643ec1381c2afd15a7441a29ed2 /llvm/lib/Target/ARM/ARMCallLowering.cpp
parentd9fb2842e75241b8404e5051b586b3f36d64f1e8 (diff)
downloadbcm5719-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.cpp28
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
OpenPOWER on IntegriCloud