Skip to content

Commit 0d1308a

Browse files
committed
[AArch64][GlobalISel] Support returned argument with multiple registers
The call lowering code assumed that a returned argument could only consist of one register. Pass an ArrayRef<Register> instead of Register to make sure that all parts get assigned. Fixes #53315. Differential Revision: https://reviews.llvm.org/D117866
1 parent e7c9a6c commit 0d1308a

File tree

4 files changed

+39
-13
lines changed

4 files changed

+39
-13
lines changed

llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -388,12 +388,12 @@ class CallLowering {
388388
/// \p Handler to move them to the assigned locations.
389389
///
390390
/// \return True if everything has succeeded, false otherwise.
391-
bool determineAndHandleAssignments(ValueHandler &Handler,
392-
ValueAssigner &Assigner,
393-
SmallVectorImpl<ArgInfo> &Args,
394-
MachineIRBuilder &MIRBuilder,
395-
CallingConv::ID CallConv, bool IsVarArg,
396-
Register ThisReturnReg = Register()) const;
391+
bool
392+
determineAndHandleAssignments(ValueHandler &Handler, ValueAssigner &Assigner,
393+
SmallVectorImpl<ArgInfo> &Args,
394+
MachineIRBuilder &MIRBuilder,
395+
CallingConv::ID CallConv, bool IsVarArg,
396+
ArrayRef<Register> ThisReturnRegs = None) const;
397397

398398
/// Use \p Handler to insert code to handle the argument/return values
399399
/// represented by \p Args. It's expected determineAssignments previously
@@ -402,7 +402,7 @@ class CallLowering {
402402
CCState &CCState,
403403
SmallVectorImpl<CCValAssign> &ArgLocs,
404404
MachineIRBuilder &MIRBuilder,
405-
Register ThisReturnReg = Register()) const;
405+
ArrayRef<Register> ThisReturnRegs = None) const;
406406

407407
/// Check whether parameters to a call that are passed in callee saved
408408
/// registers are the same as from the calling function. This needs to be

llvm/lib/CodeGen/GlobalISel/CallLowering.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,8 @@ static void buildCopyToRegs(MachineIRBuilder &B, ArrayRef<Register> DstRegs,
509509
bool CallLowering::determineAndHandleAssignments(
510510
ValueHandler &Handler, ValueAssigner &Assigner,
511511
SmallVectorImpl<ArgInfo> &Args, MachineIRBuilder &MIRBuilder,
512-
CallingConv::ID CallConv, bool IsVarArg, Register ThisReturnReg) const {
512+
CallingConv::ID CallConv, bool IsVarArg,
513+
ArrayRef<Register> ThisReturnRegs) const {
513514
MachineFunction &MF = MIRBuilder.getMF();
514515
const Function &F = MF.getFunction();
515516
SmallVector<CCValAssign, 16> ArgLocs;
@@ -519,7 +520,7 @@ bool CallLowering::determineAndHandleAssignments(
519520
return false;
520521

521522
return handleAssignments(Handler, Args, CCInfo, ArgLocs, MIRBuilder,
522-
ThisReturnReg);
523+
ThisReturnRegs);
523524
}
524525

525526
static unsigned extendOpFromFlags(llvm::ISD::ArgFlagsTy Flags) {
@@ -596,7 +597,7 @@ bool CallLowering::handleAssignments(ValueHandler &Handler,
596597
CCState &CCInfo,
597598
SmallVectorImpl<CCValAssign> &ArgLocs,
598599
MachineIRBuilder &MIRBuilder,
599-
Register ThisReturnReg) const {
600+
ArrayRef<Register> ThisReturnRegs) const {
600601
MachineFunction &MF = MIRBuilder.getMF();
601602
MachineRegisterInfo &MRI = MF.getRegInfo();
602603
const Function &F = MF.getFunction();
@@ -740,10 +741,10 @@ bool CallLowering::handleAssignments(ValueHandler &Handler,
740741

741742
assert(!VA.needsCustom() && "custom loc should have been handled already");
742743

743-
if (i == 0 && ThisReturnReg.isValid() &&
744+
if (i == 0 && !ThisReturnRegs.empty() &&
744745
Handler.isIncomingArgumentHandler() &&
745746
isTypeIsValidForThisReturn(ValVT)) {
746-
Handler.assignValueToReg(Args[i].Regs[i], ThisReturnReg, VA);
747+
Handler.assignValueToReg(ArgReg, ThisReturnRegs[Part], VA);
747748
continue;
748749
}
749750

llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1179,7 +1179,7 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
11791179
if (!determineAndHandleAssignments(
11801180
UsingReturnedArg ? ReturnedArgHandler : Handler, Assigner, InArgs,
11811181
MIRBuilder, Info.CallConv, Info.IsVarArg,
1182-
UsingReturnedArg ? OutArgs[0].Regs[0] : Register()))
1182+
UsingReturnedArg ? makeArrayRef(OutArgs[0].Regs) : None))
11831183
return false;
11841184
}
11851185

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -O0 -mtriple=aarch64-unknown-linux-gnu -verify-machineinstrs < %s | FileCheck %s
3+
4+
define void @test() nounwind {
5+
; CHECK-LABEL: test:
6+
; CHECK: // %bb.0:
7+
; CHECK-NEXT: sub sp, sp, #32
8+
; CHECK-NEXT: str x30, [sp, #16] // 8-byte Folded Spill
9+
; CHECK-NEXT: mov x1, xzr
10+
; CHECK-NEXT: str x1, [sp, #8] // 8-byte Folded Spill
11+
; CHECK-NEXT: mov x0, x1
12+
; CHECK-NEXT: bl returns_arg
13+
; CHECK-NEXT: ldr x1, [sp, #8] // 8-byte Folded Reload
14+
; CHECK-NEXT: mov x0, x1
15+
; CHECK-NEXT: bl accepts_arg
16+
; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload
17+
; CHECK-NEXT: add sp, sp, #32
18+
; CHECK-NEXT: ret
19+
%x = call i128 @returns_arg(i128 0)
20+
call void @accepts_arg(i128 %x)
21+
ret void
22+
}
23+
24+
declare i128 @returns_arg(i128 returned)
25+
declare void @accepts_arg(i128)

0 commit comments

Comments
 (0)