[llvm] 2b731b3 - AMDGPU: Take care of "tied" operand when removeOperand

Changpeng Fang via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 28 17:31:59 PDT 2022


Author: Changpeng Fang
Date: 2022-07-28T17:30:49-07:00
New Revision: 2b731b30a7e7948ba37649ab1af4be542578104a

URL: https://github.com/llvm/llvm-project/commit/2b731b30a7e7948ba37649ab1af4be542578104a
DIFF: https://github.com/llvm/llvm-project/commit/2b731b30a7e7948ba37649ab1af4be542578104a.diff

LOG: AMDGPU: Take care of "tied" operand when removeOperand

Summary:
  Flat scratch load of D16 type by default has tied vdst_in operand (with vdst). This should be taken
care of at the time of "removeOperand" in eliminateFrameIndex. Otherwise we will hit an assert saying
"Cannot move tied operands". This patch unties vdst_in before the move, and retie it with vdst afterwards.

Reviewers:
  arsenm, foad

Differential Revision: https://reviews.llvm.org/D130537

Added: 
    llvm/test/CodeGen/AMDGPU/frame-index-elimination-tied-operand.mir

Modified: 
    llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
    llvm/test/CodeGen/AMDGPU/frame-index-elimination.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
index b32d5bb04d5b..17f56a3053ae 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
@@ -2154,8 +2154,27 @@ void SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
             }
 
             if (NewOpc != -1) {
+              // removeOperand doesn't fixup tied operand indexes at it goes, so
+              // it asserts. Untie vdst_in for now and retie them afterwards.
+              int VDstIn = AMDGPU::getNamedOperandIdx(Opc,
+                                                     AMDGPU::OpName::vdst_in);
+              bool TiedVDst = VDstIn != -1 &&
+                              MI->getOperand(VDstIn).isReg() &&
+                              MI->getOperand(VDstIn).isTied();
+              if (TiedVDst)
+                MI->untieRegOperand(VDstIn);
+
               MI->removeOperand(
                   AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::saddr));
+
+              if (TiedVDst) {
+                int NewVDst =
+                    AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst);
+                int NewVDstIn =
+                    AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst_in);
+                assert (NewVDst != -1 && NewVDstIn != -1 && "Must be tied!");
+                MI->tieOperands(NewVDst, NewVDstIn);
+              }
               MI->setDesc(TII->get(NewOpc));
               return;
             }

diff  --git a/llvm/test/CodeGen/AMDGPU/frame-index-elimination-tied-operand.mir b/llvm/test/CodeGen/AMDGPU/frame-index-elimination-tied-operand.mir
new file mode 100644
index 000000000000..d7a1b2d29b26
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/frame-index-elimination-tied-operand.mir
@@ -0,0 +1,39 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -run-pass=prologepilog -o - %s | FileCheck -check-prefix=GFX11 %s
+...
+---
+name:            tied_operand_test
+tracksRegLiveness: true
+stack:
+  - { id: 0, type: default, offset: 0, size: 2, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      local-offset: 0, debug-info-variable: '', debug-info-expression: '',
+      debug-info-location: '' }
+
+machineFunctionInfo:
+  isEntryFunction: true
+  stackPtrOffsetReg: '$sgpr32'
+
+body:             |
+  bb.0.entry:
+    liveins: $sgpr0_sgpr1
+
+    ; GFX11-LABEL: name: tied_operand_test
+    ; GFX11: liveins: $sgpr0_sgpr1
+    ; GFX11-NEXT: {{  $}}
+    ; GFX11-NEXT: renamable $vgpr0 = V_MOV_B32_e32 123, implicit $exec
+    ; GFX11-NEXT: renamable $vgpr0 = SCRATCH_LOAD_SHORT_D16_HI_ST 4, 0, killed renamable $vgpr0, implicit $exec, implicit $flat_scr
+    ; GFX11-NEXT: renamable $sgpr0 = S_LOAD_DWORD_IMM killed renamable $sgpr0_sgpr1, 4, 0
+    ; GFX11-NEXT: renamable $sgpr0 = S_LSHL_B32 killed renamable $sgpr0, 1, implicit-def dead $scc
+    ; GFX11-NEXT: renamable $vgpr1 = COPY killed renamable $sgpr0, implicit $exec
+    ; GFX11-NEXT: DS_WRITE_B32_gfx9 killed renamable $vgpr1, killed renamable $vgpr0, 8, 0, implicit $exec
+    ; GFX11-NEXT: S_ENDPGM 0
+    renamable $vgpr0 = V_MOV_B32_e32 123, implicit $exec
+    renamable $vgpr0 = SCRATCH_LOAD_SHORT_D16_HI_SADDR %stack.0, 0, 0, killed renamable $vgpr0, implicit $exec, implicit $flat_scr
+    renamable $sgpr0 = S_LOAD_DWORD_IMM killed renamable $sgpr0_sgpr1, 4, 0
+    renamable $sgpr0 = S_LSHL_B32 killed renamable $sgpr0, 1, implicit-def dead $scc
+    renamable $vgpr1 = COPY killed renamable $sgpr0, implicit $exec
+    DS_WRITE_B32_gfx9 killed renamable $vgpr1, killed renamable $vgpr0, 8, 0, implicit $exec
+    S_ENDPGM 0
+
+...

diff  --git a/llvm/test/CodeGen/AMDGPU/frame-index-elimination.ll b/llvm/test/CodeGen/AMDGPU/frame-index-elimination.ll
index e086d504130a..0556cf78683e 100644
--- a/llvm/test/CodeGen/AMDGPU/frame-index-elimination.ll
+++ b/llvm/test/CodeGen/AMDGPU/frame-index-elimination.ll
@@ -1,6 +1,7 @@
 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=kaveri -mattr=-promote-alloca -amdgpu-sroa=0 -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,CI,MUBUF %s
 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -mattr=-promote-alloca -amdgpu-sroa=0 -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX9,GFX9-MUBUF,MUBUF %s
 ; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -mattr=-promote-alloca,+enable-flat-scratch -amdgpu-sroa=0 -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefixes=GCN,GFX9,GFX9-FLATSCR %s
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 < %s | FileCheck --check-prefixes=GFX11 %s
 
 ; Test that non-entry function frame indices are expanded properly to
 ; give an index relative to the scratch wave offset register
@@ -305,4 +306,31 @@ ret:
   ret void
 }
 
+%struct0 = type { [4224 x %type.i16] }
+%type.i16 = type { i16 }
+ at _ZZN0 = external hidden addrspace(3) global %struct0, align 8
+
+; GFX11-LABEL: tied_operand_test:
+; GFX11:       ; %bb.0: ; %entry
+; GFX11:         scratch_load_d16_hi_b16 [[LDRESULT:v[0-9]+]], off, off offset:4
+; GFX11-NEXT:    s_waitcnt vmcnt(0)
+; GFX11-NEXT:    ds_store_b32 v{{[0-9]+}}, [[LDRESULT]] offset:8
+; GFX11-NEXT:    s_endpgm
+define protected amdgpu_kernel void @tied_operand_test(i1 %c1, i1 %c2, i32 %val) {
+entry:
+  %scratch0 = alloca i16, align 4, addrspace(5)
+  %scratch1 = alloca i16, align 4, addrspace(5)
+  %first = select i1 %c1, i16 addrspace(5)* %scratch0, i16 addrspace(5)* %scratch1
+  %spec.select = select i1 %c2, i16 addrspace(5)* %first, i16 addrspace(5)* %scratch0
+  %dead.load = load i16, i16 addrspace(5)* %spec.select, align 2
+  %scratch0.load = load i16, i16 addrspace(5)* %scratch0, align 4
+  %add4 = add nuw nsw i32 %val, 4
+  %addr0 = getelementptr inbounds %struct0, %struct0 addrspace(3)* bitcast (%struct0 addrspace(3)* @_ZZN0 to %struct0 addrspace(3)*), i32 0, i32 0, i32 %add4, i32 0
+  store i16 123, i16 addrspace(3)* %addr0, align 2
+  %add5 = add nuw nsw i32 %val, 5
+  %addr1 = getelementptr inbounds %struct0, %struct0 addrspace(3)* bitcast (%struct0 addrspace(3)* @_ZZN0 to %struct0 addrspace(3)*), i32 0, i32 0, i32 %add5, i32 0
+  store i16 %scratch0.load, i16 addrspace(3)* %addr1, align 2
+  ret void
+}
+
 attributes #0 = { nounwind }


        


More information about the llvm-commits mailing list