Commit c017cec6 authored by Tom Stellard's avatar Tom Stellard
Browse files

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

------------------------------------------------------------------------

llvm-svn: 288106
parent a63d6b20
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -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) {
+49 −0
Original line number Diff line number Diff line
;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 }