summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2016-11-29 03:41:29 +0000
committerTom Stellard <thomas.stellard@amd.com>2016-11-29 03:41:29 +0000
commitc95a7375b133e484f71d1c8828312f824573d275 (patch)
tree3a89127a5fab8eecebe49ec52f72483b0541a2a5
parent25e2616626caafb896517e18cd8aa724fba2b200 (diff)
downloadllvm-c95a7375b133e484f71d1c8828312f824573d275.tar.gz
Merging r287339:
------------------------------------------------------------------------ r287339 | nhaehnle | 2016-11-18 03:55:52 -0800 (Fri, 18 Nov 2016) | 20 lines AMDGPU: Fix legalization of MUBUF instructions in shaders Summary: The addr64-based legalization is incorrect for MUBUF instructions with idxen set as well as for BUFFER_LOAD/STORE_FORMAT_* instructions. This affects e.g. shaders that access buffer textures. Since we never actually need the addr64-legalization in shaders, this patch takes the easy route and keys off the calling convention. If this ever affects (non-OpenGL) compute, the type of legalization needs to be chosen based on some TSFlag. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98664 Reviewers: arsenm, tstellarAMD Subscribers: kzhuravl, wdng, yaxunl, tony-tye, llvm-commits Differential Revision: https://reviews.llvm.org/D26747 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_39@288106 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/AMDGPU/SIInstrInfo.cpp18
-rw-r--r--test/CodeGen/AMDGPU/mubuf-shader-vgpr.ll49
2 files changed, 62 insertions, 5 deletions
diff --git a/lib/Target/AMDGPU/SIInstrInfo.cpp b/lib/Target/AMDGPU/SIInstrInfo.cpp
index 5cc6a4e0e83e..919081902a9c 100644
--- a/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -2203,7 +2203,8 @@ void SIInstrInfo::legalizeOperandsSMRD(MachineRegisterInfo &MRI,
}
void SIInstrInfo::legalizeOperands(MachineInstr &MI) const {
- MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
+ MachineFunction &MF = *MI.getParent()->getParent();
+ MachineRegisterInfo &MRI = MF.getRegInfo();
// Legalize VOP2
if (isVOP2(MI) || isVOPC(MI)) {
@@ -2321,8 +2322,14 @@ void SIInstrInfo::legalizeOperands(MachineInstr &MI) const {
return;
}
- // Legalize MIMG
- if (isMIMG(MI)) {
+ // Legalize MIMG and MUBUF/MTBUF for shaders.
+ //
+ // Shaders only generate MUBUF/MTBUF instructions via intrinsics or via
+ // scratch memory access. In both cases, the legalization never involves
+ // conversion to the addr64 form.
+ if (isMIMG(MI) ||
+ (AMDGPU::isShader(MF.getFunction()->getCallingConv()) &&
+ (isMUBUF(MI) || isMTBUF(MI)))) {
MachineOperand *SRsrc = getNamedOperand(MI, AMDGPU::OpName::srsrc);
if (SRsrc && !RI.isSGPRClass(MRI.getRegClass(SRsrc->getReg()))) {
unsigned SGPR = readlaneVGPRToSGPR(SRsrc->getReg(), MI, MRI);
@@ -2337,9 +2344,10 @@ void SIInstrInfo::legalizeOperands(MachineInstr &MI) const {
return;
}
- // Legalize MUBUF* instructions
+ // Legalize MUBUF* instructions by converting to addr64 form.
// FIXME: If we start using the non-addr64 instructions for compute, we
- // may need to legalize them here.
+ // may need to legalize them as above. This especially applies to the
+ // buffer_load_format_* variants and variants with idxen (or bothen).
int SRsrcIdx =
AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::srsrc);
if (SRsrcIdx != -1) {
diff --git a/test/CodeGen/AMDGPU/mubuf-shader-vgpr.ll b/test/CodeGen/AMDGPU/mubuf-shader-vgpr.ll
new file mode 100644
index 000000000000..b528577a7eaa
--- /dev/null
+++ b/test/CodeGen/AMDGPU/mubuf-shader-vgpr.ll
@@ -0,0 +1,49 @@
+;RUN: llc < %s -march=amdgcn -mcpu=verde -verify-machineinstrs | FileCheck %s -check-prefix=CHECK
+;RUN: llc < %s -march=amdgcn -mcpu=tonga -verify-machineinstrs | FileCheck %s -check-prefix=CHECK
+
+; Test that buffer_load_format with VGPR resource descriptor is properly
+; legalized.
+
+; CHECK-LABEL: {{^}}test_none:
+; CHECK: buffer_load_format_x v0, off, {{s\[[0-9]+:[0-9]+\]}}, 0{{$}}
+define amdgpu_vs float @test_none(<4 x i32> addrspace(2)* inreg %base, i32 %i) {
+main_body:
+ %ptr = getelementptr <4 x i32>, <4 x i32> addrspace(2)* %base, i32 %i
+ %tmp2 = load <4 x i32>, <4 x i32> addrspace(2)* %ptr, align 32
+ %tmp7 = call float @llvm.amdgcn.buffer.load.format.f32(<4 x i32> %tmp2, i32 0, i32 0, i1 0, i1 0)
+ ret float %tmp7
+}
+
+; CHECK-LABEL: {{^}}test_idxen:
+; CHECK: buffer_load_format_x v0, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0 idxen{{$}}
+define amdgpu_vs float @test_idxen(<4 x i32> addrspace(2)* inreg %base, i32 %i) {
+main_body:
+ %ptr = getelementptr <4 x i32>, <4 x i32> addrspace(2)* %base, i32 %i
+ %tmp2 = load <4 x i32>, <4 x i32> addrspace(2)* %ptr, align 32
+ %tmp7 = call float @llvm.amdgcn.buffer.load.format.f32(<4 x i32> %tmp2, i32 undef, i32 0, i1 0, i1 0)
+ ret float %tmp7
+}
+
+; CHECK-LABEL: {{^}}test_offen:
+; CHECK: buffer_load_format_x v0, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0 offen{{$}}
+define amdgpu_vs float @test_offen(<4 x i32> addrspace(2)* inreg %base, i32 %i) {
+main_body:
+ %ptr = getelementptr <4 x i32>, <4 x i32> addrspace(2)* %base, i32 %i
+ %tmp2 = load <4 x i32>, <4 x i32> addrspace(2)* %ptr, align 32
+ %tmp7 = call float @llvm.amdgcn.buffer.load.format.f32(<4 x i32> %tmp2, i32 0, i32 undef, i1 0, i1 0)
+ ret float %tmp7
+}
+
+; CHECK-LABEL: {{^}}test_both:
+; CHECK: buffer_load_format_x v0, {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 idxen offen{{$}}
+define amdgpu_vs float @test_both(<4 x i32> addrspace(2)* inreg %base, i32 %i) {
+main_body:
+ %ptr = getelementptr <4 x i32>, <4 x i32> addrspace(2)* %base, i32 %i
+ %tmp2 = load <4 x i32>, <4 x i32> addrspace(2)* %ptr, align 32
+ %tmp7 = call float @llvm.amdgcn.buffer.load.format.f32(<4 x i32> %tmp2, i32 undef, i32 undef, i1 0, i1 0)
+ ret float %tmp7
+}
+
+declare float @llvm.amdgcn.buffer.load.format.f32(<4 x i32>, i32, i32, i1, i1) nounwind readonly
+
+attributes #0 = { nounwind readnone }