summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMCallLowering.cpp
diff options
context:
space:
mode:
authorDiana Picus <diana.picus@linaro.org>2017-06-02 10:16:48 +0000
committerDiana Picus <diana.picus@linaro.org>2017-06-02 10:16:48 +0000
commite7aa90987d2e4fe71ab683ebca80a01d29d4ff7b (patch)
treeea3b95ec40989b6fe6e75669b628c391c5c1ea52 /llvm/lib/Target/ARM/ARMCallLowering.cpp
parentc226303d3ee71f1d874ad8f6809ed0400624b5e5 (diff)
downloadbcm5719-llvm-e7aa90987d2e4fe71ab683ebca80a01d29d4ff7b.tar.gz
bcm5719-llvm-e7aa90987d2e4fe71ab683ebca80a01d29d4ff7b.zip
[ARM] GlobalISel: Support struct params/returns
Very very similar to the support for arrays. As with arrays, we don't support returning large structs that wouldn't fit in R0-R3. Most front-ends would likely use sret arguments for that anyway. The only significant difference is that when splitting a struct, we need to make sure we set the correct original alignment on each member, otherwise it may get split incorrectly between stack and registers. llvm-svn: 304536
Diffstat (limited to 'llvm/lib/Target/ARM/ARMCallLowering.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMCallLowering.cpp14
1 files changed, 11 insertions, 3 deletions
diff --git a/llvm/lib/Target/ARM/ARMCallLowering.cpp b/llvm/lib/Target/ARM/ARMCallLowering.cpp
index 31a2f499a9a..a33d025d114 100644
--- a/llvm/lib/Target/ARM/ARMCallLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMCallLowering.cpp
@@ -34,7 +34,7 @@ ARMCallLowering::ARMCallLowering(const ARMTargetLowering &TLI)
static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI,
Type *T) {
- if (T->isArrayTy())
+ if (T->isArrayTy() || T->isStructTy())
return true;
EVT VT = TLI.getValueType(DL, T, true);
@@ -167,8 +167,11 @@ void ARMCallLowering::splitToValueTypes(
if (SplitVTs.size() == 1) {
// Even if there is no splitting to do, we still want to replace the
// original type (e.g. pointer type -> integer).
- SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx),
- OrigArg.Flags, OrigArg.IsFixed);
+ auto Flags = OrigArg.Flags;
+ unsigned OriginalAlignment = DL.getABITypeAlignment(OrigArg.Ty);
+ Flags.setOrigAlign(OriginalAlignment);
+ SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx), Flags,
+ OrigArg.IsFixed);
return;
}
@@ -177,6 +180,10 @@ void ARMCallLowering::splitToValueTypes(
EVT SplitVT = SplitVTs[i];
Type *SplitTy = SplitVT.getTypeForEVT(Ctx);
auto Flags = OrigArg.Flags;
+
+ unsigned OriginalAlignment = DL.getABITypeAlignment(SplitTy);
+ Flags.setOrigAlign(OriginalAlignment);
+
bool NeedsConsecutiveRegisters =
TLI.functionArgumentNeedsConsecutiveRegisters(
SplitTy, F->getCallingConv(), F->isVarArg());
@@ -185,6 +192,7 @@ void ARMCallLowering::splitToValueTypes(
if (i == e - 1)
Flags.setInConsecutiveRegsLast();
}
+
SplitArgs.push_back(
ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*SplitTy, DL)),
SplitTy, Flags, OrigArg.IsFixed});
OpenPOWER on IntegriCloud