diff options
author | Tim Northover <tnorthover@apple.com> | 2017-08-21 21:56:11 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2017-08-21 21:56:11 +0000 |
commit | ef1fc5ae89e6fdb1c94022506ca8188782548852 (patch) | |
tree | a026dc3a1fd162564468dd61ced68994f95954a1 /llvm/lib | |
parent | 010fc49e42f20d5ae2b9893576fee411f8986685 (diff) | |
download | bcm5719-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.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64CallLowering.h | 1 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelLowering.h | 7 |
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; }; |