summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2017-08-21 21:56:11 +0000
committerTim Northover <tnorthover@apple.com>2017-08-21 21:56:11 +0000
commitef1fc5ae89e6fdb1c94022506ca8188782548852 (patch)
treea026dc3a1fd162564468dd61ced68994f95954a1 /llvm/lib
parent010fc49e42f20d5ae2b9893576fee411f8986685 (diff)
downloadbcm5719-llvm-ef1fc5ae89e6fdb1c94022506ca8188782548852.tar.gz
bcm5719-llvm-ef1fc5ae89e6fdb1c94022506ca8188782548852.zip
GlobalISel (AArch64): fix ABI at border between GPRs and SP.
If a struct would end up half in GPRs and half on SP the ABI says it should actually go entirely on the stack. We were getting this wrong in GlobalISel before, causing compatibility issues. llvm-svn: 311388
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AArch64/AArch64CallLowering.cpp17
-rw-r--r--llvm/lib/Target/AArch64/AArch64CallLowering.h1
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.h7
3 files changed, 15 insertions, 10 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
index a1cc0b53a43..13769a22800 100644
--- a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
@@ -172,7 +172,7 @@ struct OutgoingArgHandler : public CallLowering::ValueHandler {
void AArch64CallLowering::splitToValueTypes(
const ArgInfo &OrigArg, SmallVectorImpl<ArgInfo> &SplitArgs,
- const DataLayout &DL, MachineRegisterInfo &MRI,
+ const DataLayout &DL, MachineRegisterInfo &MRI, CallingConv::ID CallConv,
const SplitArgTy &PerformArgSplit) const {
const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>();
LLVMContext &Ctx = OrigArg.Ty->getContext();
@@ -190,14 +190,19 @@ void AArch64CallLowering::splitToValueTypes(
}
unsigned FirstRegIdx = SplitArgs.size();
+ bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters(
+ OrigArg.Ty, CallConv, false);
for (auto SplitVT : SplitVTs) {
- // FIXME: set split flags if they're actually used (e.g. i128 on AAPCS).
Type *SplitTy = SplitVT.getTypeForEVT(Ctx);
SplitArgs.push_back(
ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*SplitTy, DL)),
SplitTy, OrigArg.Flags, OrigArg.IsFixed});
+ if (NeedsRegBlock)
+ SplitArgs.back().Flags.setInConsecutiveRegs();
}
+ SplitArgs.back().Flags.setInConsecutiveRegsLast();
+
for (unsigned i = 0; i < Offsets.size(); ++i)
PerformArgSplit(SplitArgs[FirstRegIdx + i].Reg, Offsets[i] * 8);
}
@@ -220,7 +225,7 @@ bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);
SmallVector<ArgInfo, 8> SplitArgs;
- splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
+ splitToValueTypes(OrigArg, SplitArgs, DL, MRI, F.getCallingConv(),
[&](unsigned Reg, uint64_t Offset) {
MIRBuilder.buildExtract(Reg, VReg, Offset);
});
@@ -250,7 +255,7 @@ bool AArch64CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
LLT Ty = MRI.getType(VRegs[i]);
unsigned Dst = VRegs[i];
- splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
+ splitToValueTypes(OrigArg, SplitArgs, DL, MRI, F.getCallingConv(),
[&](unsigned Reg, uint64_t Offset) {
if (!Split) {
Split = true;
@@ -311,7 +316,7 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
SmallVector<ArgInfo, 8> SplitArgs;
for (auto &OrigArg : OrigArgs) {
- splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
+ splitToValueTypes(OrigArg, SplitArgs, DL, MRI, CallConv,
[&](unsigned Reg, uint64_t Offset) {
MIRBuilder.buildExtract(Reg, OrigArg.Reg, Offset);
});
@@ -364,7 +369,7 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
SmallVector<uint64_t, 8> RegOffsets;
SmallVector<unsigned, 8> SplitRegs;
- splitToValueTypes(OrigRet, SplitArgs, DL, MRI,
+ splitToValueTypes(OrigRet, SplitArgs, DL, MRI, F.getCallingConv(),
[&](unsigned Reg, uint64_t Offset) {
RegOffsets.push_back(Offset);
SplitRegs.push_back(Reg);
diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.h b/llvm/lib/Target/AArch64/AArch64CallLowering.h
index ad01d0539b0..68c127fc42e 100644
--- a/llvm/lib/Target/AArch64/AArch64CallLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64CallLowering.h
@@ -56,6 +56,7 @@ private:
void splitToValueTypes(const ArgInfo &OrigArgInfo,
SmallVectorImpl<ArgInfo> &SplitArgs,
const DataLayout &DL, MachineRegisterInfo &MRI,
+ CallingConv::ID CallConv,
const SplitArgTy &SplitArg) const;
};
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 1b36a56aa16..f4e08ad165e 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -471,6 +471,9 @@ public:
MachineMemOperand::Flags getMMOFlags(const Instruction &I) const override;
+ bool functionArgumentNeedsConsecutiveRegisters(Type *Ty,
+ CallingConv::ID CallConv,
+ bool isVarArg) const override;
private:
bool isExtFreeImpl(const Instruction *Ext) const override;
@@ -640,10 +643,6 @@ private:
void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
SelectionDAG &DAG) const override;
- bool functionArgumentNeedsConsecutiveRegisters(Type *Ty,
- CallingConv::ID CallConv,
- bool isVarArg) const override;
-
bool shouldNormalizeToSelectSequence(LLVMContext &, EVT) const override;
};
OpenPOWER on IntegriCloud