xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/Target/ARM/ARMCallLowering.cpp (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 //===- llvm/lib/Target/ARM/ARMCallLowering.cpp - Call lowering ------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// This file implements the lowering of LLVM calls to machine code calls for
11 /// GlobalISel.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "ARMCallLowering.h"
16 #include "ARMBaseInstrInfo.h"
17 #include "ARMISelLowering.h"
18 #include "ARMSubtarget.h"
19 #include "Utils/ARMBaseInfo.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/CodeGen/Analysis.h"
22 #include "llvm/CodeGen/CallingConvLower.h"
23 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
24 #include "llvm/CodeGen/GlobalISel/Utils.h"
25 #include "llvm/CodeGen/LowLevelType.h"
26 #include "llvm/CodeGen/MachineBasicBlock.h"
27 #include "llvm/CodeGen/MachineFrameInfo.h"
28 #include "llvm/CodeGen/MachineFunction.h"
29 #include "llvm/CodeGen/MachineInstrBuilder.h"
30 #include "llvm/CodeGen/MachineMemOperand.h"
31 #include "llvm/CodeGen/MachineOperand.h"
32 #include "llvm/CodeGen/MachineRegisterInfo.h"
33 #include "llvm/CodeGen/TargetRegisterInfo.h"
34 #include "llvm/CodeGen/TargetSubtargetInfo.h"
35 #include "llvm/CodeGen/ValueTypes.h"
36 #include "llvm/IR/Attributes.h"
37 #include "llvm/IR/DataLayout.h"
38 #include "llvm/IR/DerivedTypes.h"
39 #include "llvm/IR/Function.h"
40 #include "llvm/IR/Type.h"
41 #include "llvm/IR/Value.h"
42 #include "llvm/Support/Casting.h"
43 #include "llvm/Support/LowLevelTypeImpl.h"
44 #include "llvm/Support/MachineValueType.h"
45 #include <algorithm>
46 #include <cassert>
47 #include <cstdint>
48 #include <utility>
49 
50 using namespace llvm;
51 
ARMCallLowering(const ARMTargetLowering & TLI)52 ARMCallLowering::ARMCallLowering(const ARMTargetLowering &TLI)
53     : CallLowering(&TLI) {}
54 
isSupportedType(const DataLayout & DL,const ARMTargetLowering & TLI,Type * T)55 static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI,
56                             Type *T) {
57   if (T->isArrayTy())
58     return isSupportedType(DL, TLI, T->getArrayElementType());
59 
60   if (T->isStructTy()) {
61     // For now we only allow homogeneous structs that we can manipulate with
62     // G_MERGE_VALUES and G_UNMERGE_VALUES
63     auto StructT = cast<StructType>(T);
64     for (unsigned i = 1, e = StructT->getNumElements(); i != e; ++i)
65       if (StructT->getElementType(i) != StructT->getElementType(0))
66         return false;
67     return isSupportedType(DL, TLI, StructT->getElementType(0));
68   }
69 
70   EVT VT = TLI.getValueType(DL, T, true);
71   if (!VT.isSimple() || VT.isVector() ||
72       !(VT.isInteger() || VT.isFloatingPoint()))
73     return false;
74 
75   unsigned VTSize = VT.getSimpleVT().getSizeInBits();
76 
77   if (VTSize == 64)
78     // FIXME: Support i64 too
79     return VT.isFloatingPoint();
80 
81   return VTSize == 1 || VTSize == 8 || VTSize == 16 || VTSize == 32;
82 }
83 
84 namespace {
85 
86 /// Helper class for values going out through an ABI boundary (used for handling
87 /// function return values and call parameters).
88 struct ARMOutgoingValueHandler : public CallLowering::OutgoingValueHandler {
ARMOutgoingValueHandler__anon44ebfca30111::ARMOutgoingValueHandler89   ARMOutgoingValueHandler(MachineIRBuilder &MIRBuilder,
90                           MachineRegisterInfo &MRI, MachineInstrBuilder &MIB)
91       : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
92 
getStackAddress__anon44ebfca30111::ARMOutgoingValueHandler93   Register getStackAddress(uint64_t Size, int64_t Offset,
94                            MachinePointerInfo &MPO,
95                            ISD::ArgFlagsTy Flags) override {
96     assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
97            "Unsupported size");
98 
99     LLT p0 = LLT::pointer(0, 32);
100     LLT s32 = LLT::scalar(32);
101     auto SPReg = MIRBuilder.buildCopy(p0, Register(ARM::SP));
102 
103     auto OffsetReg = MIRBuilder.buildConstant(s32, Offset);
104 
105     auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
106 
107     MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
108     return AddrReg.getReg(0);
109   }
110 
assignValueToReg__anon44ebfca30111::ARMOutgoingValueHandler111   void assignValueToReg(Register ValVReg, Register PhysReg,
112                         CCValAssign &VA) override {
113     assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
114     assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
115 
116     assert(VA.getValVT().getSizeInBits() <= 64 && "Unsupported value size");
117     assert(VA.getLocVT().getSizeInBits() <= 64 && "Unsupported location size");
118 
119     Register ExtReg = extendRegister(ValVReg, VA);
120     MIRBuilder.buildCopy(PhysReg, ExtReg);
121     MIB.addUse(PhysReg, RegState::Implicit);
122   }
123 
assignValueToAddress__anon44ebfca30111::ARMOutgoingValueHandler124   void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size,
125                             MachinePointerInfo &MPO, CCValAssign &VA) override {
126     assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
127            "Unsupported size");
128 
129     Register ExtReg = extendRegister(ValVReg, VA);
130     auto MMO = MIRBuilder.getMF().getMachineMemOperand(
131         MPO, MachineMemOperand::MOStore, VA.getLocVT().getStoreSize(),
132         Align(1));
133     MIRBuilder.buildStore(ExtReg, Addr, *MMO);
134   }
135 
assignCustomValue__anon44ebfca30111::ARMOutgoingValueHandler136   unsigned assignCustomValue(const CallLowering::ArgInfo &Arg,
137                              ArrayRef<CCValAssign> VAs) override {
138     assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet");
139 
140     CCValAssign VA = VAs[0];
141     assert(VA.needsCustom() && "Value doesn't need custom handling");
142 
143     // Custom lowering for other types, such as f16, is currently not supported
144     if (VA.getValVT() != MVT::f64)
145       return 0;
146 
147     CCValAssign NextVA = VAs[1];
148     assert(NextVA.needsCustom() && "Value doesn't need custom handling");
149     assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
150 
151     assert(VA.getValNo() == NextVA.getValNo() &&
152            "Values belong to different arguments");
153 
154     assert(VA.isRegLoc() && "Value should be in reg");
155     assert(NextVA.isRegLoc() && "Value should be in reg");
156 
157     Register NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
158                           MRI.createGenericVirtualRegister(LLT::scalar(32))};
159     MIRBuilder.buildUnmerge(NewRegs, Arg.Regs[0]);
160 
161     bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
162     if (!IsLittle)
163       std::swap(NewRegs[0], NewRegs[1]);
164 
165     assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
166     assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
167 
168     return 1;
169   }
170 
171   MachineInstrBuilder MIB;
172 };
173 
174 } // end anonymous namespace
175 
176 /// Lower the return value for the already existing \p Ret. This assumes that
177 /// \p MIRBuilder's insertion point is correct.
lowerReturnVal(MachineIRBuilder & MIRBuilder,const Value * Val,ArrayRef<Register> VRegs,MachineInstrBuilder & Ret) const178 bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder,
179                                      const Value *Val, ArrayRef<Register> VRegs,
180                                      MachineInstrBuilder &Ret) const {
181   if (!Val)
182     // Nothing to do here.
183     return true;
184 
185   auto &MF = MIRBuilder.getMF();
186   const auto &F = MF.getFunction();
187 
188   const auto &DL = MF.getDataLayout();
189   auto &TLI = *getTLI<ARMTargetLowering>();
190   if (!isSupportedType(DL, TLI, Val->getType()))
191     return false;
192 
193   ArgInfo OrigRetInfo(VRegs, Val->getType());
194   setArgFlags(OrigRetInfo, AttributeList::ReturnIndex, DL, F);
195 
196   SmallVector<ArgInfo, 4> SplitRetInfos;
197   splitToValueTypes(OrigRetInfo, SplitRetInfos, DL, F.getCallingConv());
198 
199   CCAssignFn *AssignFn =
200       TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg());
201 
202   OutgoingValueAssigner RetAssigner(AssignFn);
203   ARMOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
204   return determineAndHandleAssignments(RetHandler, RetAssigner, SplitRetInfos,
205                                        MIRBuilder, F.getCallingConv(),
206                                        F.isVarArg());
207 }
208 
lowerReturn(MachineIRBuilder & MIRBuilder,const Value * Val,ArrayRef<Register> VRegs,FunctionLoweringInfo & FLI) const209 bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
210                                   const Value *Val, ArrayRef<Register> VRegs,
211                                   FunctionLoweringInfo &FLI) const {
212   assert(!Val == VRegs.empty() && "Return value without a vreg");
213 
214   auto const &ST = MIRBuilder.getMF().getSubtarget<ARMSubtarget>();
215   unsigned Opcode = ST.getReturnOpcode();
216   auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL));
217 
218   if (!lowerReturnVal(MIRBuilder, Val, VRegs, Ret))
219     return false;
220 
221   MIRBuilder.insertInstr(Ret);
222   return true;
223 }
224 
225 namespace {
226 
227 /// Helper class for values coming in through an ABI boundary (used for handling
228 /// formal arguments and call return values).
229 struct ARMIncomingValueHandler : public CallLowering::IncomingValueHandler {
ARMIncomingValueHandler__anon44ebfca30211::ARMIncomingValueHandler230   ARMIncomingValueHandler(MachineIRBuilder &MIRBuilder,
231                           MachineRegisterInfo &MRI)
232       : IncomingValueHandler(MIRBuilder, MRI) {}
233 
getStackAddress__anon44ebfca30211::ARMIncomingValueHandler234   Register getStackAddress(uint64_t Size, int64_t Offset,
235                            MachinePointerInfo &MPO,
236                            ISD::ArgFlagsTy Flags) override {
237     assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
238            "Unsupported size");
239 
240     auto &MFI = MIRBuilder.getMF().getFrameInfo();
241 
242     // Byval is assumed to be writable memory, but other stack passed arguments
243     // are not.
244     const bool IsImmutable = !Flags.isByVal();
245 
246     int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable);
247     MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI);
248 
249     return MIRBuilder.buildFrameIndex(LLT::pointer(MPO.getAddrSpace(), 32), FI)
250         .getReg(0);
251   }
252 
assignValueToAddress__anon44ebfca30211::ARMIncomingValueHandler253   void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size,
254                             MachinePointerInfo &MPO, CCValAssign &VA) override {
255     assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
256            "Unsupported size");
257 
258     if (VA.getLocInfo() == CCValAssign::SExt ||
259         VA.getLocInfo() == CCValAssign::ZExt) {
260       // If the value is zero- or sign-extended, its size becomes 4 bytes, so
261       // that's what we should load.
262       Size = 4;
263       assert(MRI.getType(ValVReg).isScalar() && "Only scalars supported atm");
264 
265       auto LoadVReg = buildLoad(LLT::scalar(32), Addr, Size, MPO);
266       MIRBuilder.buildTrunc(ValVReg, LoadVReg);
267     } else {
268       // If the value is not extended, a simple load will suffice.
269       buildLoad(ValVReg, Addr, Size, MPO);
270     }
271   }
272 
buildLoad__anon44ebfca30211::ARMIncomingValueHandler273   MachineInstrBuilder buildLoad(const DstOp &Res, Register Addr, uint64_t Size,
274                                 MachinePointerInfo &MPO) {
275     MachineFunction &MF = MIRBuilder.getMF();
276 
277     auto MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOLoad, Size,
278                                        inferAlignFromPtrInfo(MF, MPO));
279     return MIRBuilder.buildLoad(Res, Addr, *MMO);
280   }
281 
assignValueToReg__anon44ebfca30211::ARMIncomingValueHandler282   void assignValueToReg(Register ValVReg, Register PhysReg,
283                         CCValAssign &VA) override {
284     assert(VA.isRegLoc() && "Value shouldn't be assigned to reg");
285     assert(VA.getLocReg() == PhysReg && "Assigning to the wrong reg?");
286 
287     uint64_t ValSize = VA.getValVT().getFixedSizeInBits();
288     uint64_t LocSize = VA.getLocVT().getFixedSizeInBits();
289 
290     assert(ValSize <= 64 && "Unsupported value size");
291     assert(LocSize <= 64 && "Unsupported location size");
292 
293     markPhysRegUsed(PhysReg);
294     if (ValSize == LocSize) {
295       MIRBuilder.buildCopy(ValVReg, PhysReg);
296     } else {
297       assert(ValSize < LocSize && "Extensions not supported");
298 
299       // We cannot create a truncating copy, nor a trunc of a physical register.
300       // Therefore, we need to copy the content of the physical register into a
301       // virtual one and then truncate that.
302       auto PhysRegToVReg = MIRBuilder.buildCopy(LLT::scalar(LocSize), PhysReg);
303       MIRBuilder.buildTrunc(ValVReg, PhysRegToVReg);
304     }
305   }
306 
assignCustomValue__anon44ebfca30211::ARMIncomingValueHandler307   unsigned assignCustomValue(const ARMCallLowering::ArgInfo &Arg,
308                              ArrayRef<CCValAssign> VAs) override {
309     assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet");
310 
311     CCValAssign VA = VAs[0];
312     assert(VA.needsCustom() && "Value doesn't need custom handling");
313 
314     // Custom lowering for other types, such as f16, is currently not supported
315     if (VA.getValVT() != MVT::f64)
316       return 0;
317 
318     CCValAssign NextVA = VAs[1];
319     assert(NextVA.needsCustom() && "Value doesn't need custom handling");
320     assert(NextVA.getValVT() == MVT::f64 && "Unsupported type");
321 
322     assert(VA.getValNo() == NextVA.getValNo() &&
323            "Values belong to different arguments");
324 
325     assert(VA.isRegLoc() && "Value should be in reg");
326     assert(NextVA.isRegLoc() && "Value should be in reg");
327 
328     Register NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
329                           MRI.createGenericVirtualRegister(LLT::scalar(32))};
330 
331     assignValueToReg(NewRegs[0], VA.getLocReg(), VA);
332     assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
333 
334     bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
335     if (!IsLittle)
336       std::swap(NewRegs[0], NewRegs[1]);
337 
338     MIRBuilder.buildMerge(Arg.Regs[0], NewRegs);
339 
340     return 1;
341   }
342 
343   /// Marking a physical register as used is different between formal
344   /// parameters, where it's a basic block live-in, and call returns, where it's
345   /// an implicit-def of the call instruction.
346   virtual void markPhysRegUsed(unsigned PhysReg) = 0;
347 };
348 
349 struct FormalArgHandler : public ARMIncomingValueHandler {
FormalArgHandler__anon44ebfca30211::FormalArgHandler350   FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
351       : ARMIncomingValueHandler(MIRBuilder, MRI) {}
352 
markPhysRegUsed__anon44ebfca30211::FormalArgHandler353   void markPhysRegUsed(unsigned PhysReg) override {
354     MIRBuilder.getMRI()->addLiveIn(PhysReg);
355     MIRBuilder.getMBB().addLiveIn(PhysReg);
356   }
357 };
358 
359 } // end anonymous namespace
360 
lowerFormalArguments(MachineIRBuilder & MIRBuilder,const Function & F,ArrayRef<ArrayRef<Register>> VRegs,FunctionLoweringInfo & FLI) const361 bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
362                                            const Function &F,
363                                            ArrayRef<ArrayRef<Register>> VRegs,
364                                            FunctionLoweringInfo &FLI) const {
365   auto &TLI = *getTLI<ARMTargetLowering>();
366   auto Subtarget = TLI.getSubtarget();
367 
368   if (Subtarget->isThumb1Only())
369     return false;
370 
371   // Quick exit if there aren't any args
372   if (F.arg_empty())
373     return true;
374 
375   if (F.isVarArg())
376     return false;
377 
378   auto &MF = MIRBuilder.getMF();
379   auto &MBB = MIRBuilder.getMBB();
380   const auto &DL = MF.getDataLayout();
381 
382   for (auto &Arg : F.args()) {
383     if (!isSupportedType(DL, TLI, Arg.getType()))
384       return false;
385     if (Arg.hasPassPointeeByValueCopyAttr())
386       return false;
387   }
388 
389   CCAssignFn *AssignFn =
390       TLI.CCAssignFnForCall(F.getCallingConv(), F.isVarArg());
391 
392   OutgoingValueAssigner ArgAssigner(AssignFn);
393   FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo());
394 
395   SmallVector<ArgInfo, 8> SplitArgInfos;
396   unsigned Idx = 0;
397   for (auto &Arg : F.args()) {
398     ArgInfo OrigArgInfo(VRegs[Idx], Arg.getType());
399 
400     setArgFlags(OrigArgInfo, Idx + AttributeList::FirstArgIndex, DL, F);
401     splitToValueTypes(OrigArgInfo, SplitArgInfos, DL, F.getCallingConv());
402 
403     Idx++;
404   }
405 
406   if (!MBB.empty())
407     MIRBuilder.setInstr(*MBB.begin());
408 
409   if (!determineAndHandleAssignments(ArgHandler, ArgAssigner, SplitArgInfos,
410                                      MIRBuilder, F.getCallingConv(),
411                                      F.isVarArg()))
412     return false;
413 
414   // Move back to the end of the basic block.
415   MIRBuilder.setMBB(MBB);
416   return true;
417 }
418 
419 namespace {
420 
421 struct CallReturnHandler : public ARMIncomingValueHandler {
CallReturnHandler__anon44ebfca30311::CallReturnHandler422   CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
423                     MachineInstrBuilder MIB)
424       : ARMIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
425 
markPhysRegUsed__anon44ebfca30311::CallReturnHandler426   void markPhysRegUsed(unsigned PhysReg) override {
427     MIB.addDef(PhysReg, RegState::Implicit);
428   }
429 
430   MachineInstrBuilder MIB;
431 };
432 
433 // FIXME: This should move to the ARMSubtarget when it supports all the opcodes.
getCallOpcode(const MachineFunction & MF,const ARMSubtarget & STI,bool isDirect)434 unsigned getCallOpcode(const MachineFunction &MF, const ARMSubtarget &STI,
435                        bool isDirect) {
436   if (isDirect)
437     return STI.isThumb() ? ARM::tBL : ARM::BL;
438 
439   if (STI.isThumb())
440     return gettBLXrOpcode(MF);
441 
442   if (STI.hasV5TOps())
443     return getBLXOpcode(MF);
444 
445   if (STI.hasV4TOps())
446     return ARM::BX_CALL;
447 
448   return ARM::BMOVPCRX_CALL;
449 }
450 } // end anonymous namespace
451 
lowerCall(MachineIRBuilder & MIRBuilder,CallLoweringInfo & Info) const452 bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const {
453   MachineFunction &MF = MIRBuilder.getMF();
454   const auto &TLI = *getTLI<ARMTargetLowering>();
455   const auto &DL = MF.getDataLayout();
456   const auto &STI = MF.getSubtarget<ARMSubtarget>();
457   const TargetRegisterInfo *TRI = STI.getRegisterInfo();
458   MachineRegisterInfo &MRI = MF.getRegInfo();
459 
460   if (STI.genLongCalls())
461     return false;
462 
463   if (STI.isThumb1Only())
464     return false;
465 
466   auto CallSeqStart = MIRBuilder.buildInstr(ARM::ADJCALLSTACKDOWN);
467 
468   // Create the call instruction so we can add the implicit uses of arg
469   // registers, but don't insert it yet.
470   bool IsDirect = !Info.Callee.isReg();
471   auto CallOpcode = getCallOpcode(MF, STI, IsDirect);
472   auto MIB = MIRBuilder.buildInstrNoInsert(CallOpcode);
473 
474   bool IsThumb = STI.isThumb();
475   if (IsThumb)
476     MIB.add(predOps(ARMCC::AL));
477 
478   MIB.add(Info.Callee);
479   if (!IsDirect) {
480     auto CalleeReg = Info.Callee.getReg();
481     if (CalleeReg && !Register::isPhysicalRegister(CalleeReg)) {
482       unsigned CalleeIdx = IsThumb ? 2 : 0;
483       MIB->getOperand(CalleeIdx).setReg(constrainOperandRegClass(
484           MF, *TRI, MRI, *STI.getInstrInfo(), *STI.getRegBankInfo(),
485           *MIB.getInstr(), MIB->getDesc(), Info.Callee, CalleeIdx));
486     }
487   }
488 
489   MIB.addRegMask(TRI->getCallPreservedMask(MF, Info.CallConv));
490 
491   SmallVector<ArgInfo, 8> ArgInfos;
492   for (auto Arg : Info.OrigArgs) {
493     if (!isSupportedType(DL, TLI, Arg.Ty))
494       return false;
495 
496     if (Arg.Flags[0].isByVal())
497       return false;
498 
499     splitToValueTypes(Arg, ArgInfos, DL, Info.CallConv);
500   }
501 
502   auto ArgAssignFn = TLI.CCAssignFnForCall(Info.CallConv, Info.IsVarArg);
503   OutgoingValueAssigner ArgAssigner(ArgAssignFn);
504   ARMOutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB);
505   if (!determineAndHandleAssignments(ArgHandler, ArgAssigner, ArgInfos,
506                                      MIRBuilder, Info.CallConv, Info.IsVarArg))
507     return false;
508 
509   // Now we can add the actual call instruction to the correct basic block.
510   MIRBuilder.insertInstr(MIB);
511 
512   if (!Info.OrigRet.Ty->isVoidTy()) {
513     if (!isSupportedType(DL, TLI, Info.OrigRet.Ty))
514       return false;
515 
516     ArgInfos.clear();
517     splitToValueTypes(Info.OrigRet, ArgInfos, DL, Info.CallConv);
518     auto RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv, Info.IsVarArg);
519     OutgoingValueAssigner Assigner(RetAssignFn);
520     CallReturnHandler RetHandler(MIRBuilder, MRI, MIB);
521     if (!determineAndHandleAssignments(RetHandler, Assigner, ArgInfos,
522                                        MIRBuilder, Info.CallConv,
523                                        Info.IsVarArg))
524       return false;
525   }
526 
527   // We now know the size of the stack - update the ADJCALLSTACKDOWN
528   // accordingly.
529   CallSeqStart.addImm(ArgAssigner.StackOffset)
530       .addImm(0)
531       .add(predOps(ARMCC::AL));
532 
533   MIRBuilder.buildInstr(ARM::ADJCALLSTACKUP)
534       .addImm(ArgAssigner.StackOffset)
535       .addImm(0)
536       .add(predOps(ARMCC::AL));
537 
538   return true;
539 }
540