Skip to content

Commit 0f50aef

Browse files
committed
AMDGPU/GlobalISel: Implement call lowering for shaders returning values
Reviewers: arsenm, nhaehnle Subscribers: kzhuravl, jvesely, wdng, yaxunl, rovka, kristof.beyls, dstuttard, tpr, t-tye, volkan, llvm-commits Differential Revision: https://reviews.llvm.org/D57166 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357964 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent ed46a5f commit 0f50aef

File tree

3 files changed

+94
-13
lines changed

3 files changed

+94
-13
lines changed

lib/Target/AMDGPU/AMDGPUCallLowering.cpp

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,94 @@
2020
#include "SIMachineFunctionInfo.h"
2121
#include "SIRegisterInfo.h"
2222
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
23+
#include "llvm/CodeGen/Analysis.h"
2324
#include "llvm/CodeGen/CallingConvLower.h"
2425
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
2526
#include "llvm/CodeGen/MachineInstrBuilder.h"
27+
#include "llvm/Support/LowLevelTypeImpl.h"
2628

2729
using namespace llvm;
2830

31+
namespace {
32+
33+
struct OutgoingArgHandler : public CallLowering::ValueHandler {
34+
OutgoingArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI,
35+
MachineInstrBuilder MIB, CCAssignFn *AssignFn)
36+
: ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
37+
38+
MachineInstrBuilder MIB;
39+
40+
unsigned getStackAddress(uint64_t Size, int64_t Offset,
41+
MachinePointerInfo &MPO) override {
42+
llvm_unreachable("not implemented");
43+
}
44+
45+
void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size,
46+
MachinePointerInfo &MPO, CCValAssign &VA) override {
47+
llvm_unreachable("not implemented");
48+
}
49+
50+
void assignValueToReg(unsigned ValVReg, unsigned PhysReg,
51+
CCValAssign &VA) override {
52+
MIB.addUse(PhysReg);
53+
MIRBuilder.buildCopy(PhysReg, ValVReg);
54+
}
55+
56+
bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
57+
CCValAssign::LocInfo LocInfo,
58+
const CallLowering::ArgInfo &Info,
59+
CCState &State) override {
60+
return AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.Flags, State);
61+
}
62+
};
63+
64+
}
65+
2966
AMDGPUCallLowering::AMDGPUCallLowering(const AMDGPUTargetLowering &TLI)
3067
: CallLowering(&TLI) {
3168
}
3269

3370
bool AMDGPUCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
3471
const Value *Val,
3572
ArrayRef<unsigned> VRegs) const {
36-
// FIXME: Add support for non-void returns.
37-
if (Val)
73+
74+
MachineFunction &MF = MIRBuilder.getMF();
75+
MachineRegisterInfo &MRI = MF.getRegInfo();
76+
SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
77+
MFI->setIfReturnsVoid(!Val);
78+
79+
if (!Val) {
80+
MIRBuilder.buildInstr(AMDGPU::S_ENDPGM).addImm(0);
81+
return true;
82+
}
83+
84+
unsigned VReg = VRegs[0];
85+
86+
const Function &F = MF.getFunction();
87+
auto &DL = F.getParent()->getDataLayout();
88+
if (!AMDGPU::isShader(F.getCallingConv()))
89+
return false;
90+
91+
92+
const AMDGPUTargetLowering &TLI = *getTLI<AMDGPUTargetLowering>();
93+
SmallVector<EVT, 4> SplitVTs;
94+
SmallVector<uint64_t, 4> Offsets;
95+
ArgInfo OrigArg{VReg, Val->getType()};
96+
setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F);
97+
ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0);
98+
99+
SmallVector<ArgInfo, 8> SplitArgs;
100+
CCAssignFn *AssignFn = CCAssignFnForReturn(F.getCallingConv(), false);
101+
for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
102+
Type *SplitTy = SplitVTs[i].getTypeForEVT(F.getContext());
103+
SplitArgs.push_back({VRegs[i], SplitTy, OrigArg.Flags, OrigArg.IsFixed});
104+
}
105+
auto RetInstr = MIRBuilder.buildInstrNoInsert(AMDGPU::SI_RETURN_TO_EPILOG);
106+
OutgoingArgHandler Handler(MIRBuilder, MRI, RetInstr, AssignFn);
107+
if (!handleAssignments(MIRBuilder, SplitArgs, Handler))
38108
return false;
109+
MIRBuilder.insertInstr(RetInstr);
39110

40-
MIRBuilder.buildInstr(AMDGPU::S_ENDPGM).addImm(0);
41111
return true;
42112
}
43113

test/CodeGen/AMDGPU/GlobalISel/irtranslator-amdgpu_vs.ll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,27 @@ define amdgpu_vs void @test_order(float inreg %arg0, float inreg %arg1, float %a
5555
ret void
5656
}
5757

58+
; CHECK-LABEL: name: ret_struct
59+
; CHECK: [[S0:%[0-9]+]]:_(s32) = COPY $sgpr0
60+
; CHECK: [[S1:%[0-9]+]]:_(s32) = COPY $sgpr1
61+
; CHECK: $sgpr0 = COPY [[S0]]
62+
; CHECK: $sgpr1 = COPY [[S1]]
63+
; CHECK: SI_RETURN_TO_EPILOG $sgpr0, $sgpr1
64+
define amdgpu_vs <{ i32, i32 }> @ret_struct(i32 inreg %arg0, i32 inreg %arg1) {
65+
main_body:
66+
%tmp0 = insertvalue <{ i32, i32 }> undef, i32 %arg0, 0
67+
%tmp1 = insertvalue <{ i32, i32 }> %tmp0, i32 %arg1, 1
68+
ret <{ i32, i32 }> %tmp1
69+
}
70+
71+
; CHECK_LABEL: name: non_void_ret
72+
; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
73+
; CHECK: $sgpr0 = COPY [[ZERO]]
74+
; SI_RETURN_TO_EPILOG $sgpr0
75+
define amdgpu_vs i32 @non_void_ret() {
76+
ret i32 0
77+
}
78+
5879
declare void @llvm.amdgcn.exp.f32(i32, i32, float, float, float, float, i1, i1) #0
5980

6081
attributes #0 = { nounwind }

test/CodeGen/AMDGPU/GlobalISel/todo.ll

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)