[llvm] [AMDGPU] Fix crash due to assertion failure (PR #123627)

Chinmay Deshpande via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 20 08:23:43 PST 2025


https://github.com/chinmaydd updated https://github.com/llvm/llvm-project/pull/123627

>From e11fa0ea43609403d82245f5aec33e75a19def37 Mon Sep 17 00:00:00 2001
From: Chinmay Deshpande <ChinmayDiwakar.Deshpande at amd.com>
Date: Mon, 20 Jan 2025 09:28:13 -0500
Subject: [PATCH] [AMDGPU] Fix crash due to assertion failure

Add check for FLAT instructions that dont use vector registers when computing VALU hazard.

Change-Id: I558aed17b109047bdc64f8a7e5f419d4d37577cf
---
 .../lib/Target/AMDGPU/GCNHazardRecognizer.cpp |   9 +-
 .../CodeGen/AMDGPU/fix-crash-valu-hazard.ll   | 130 ++++++++++++++++++
 .../CodeGen/AMDGPU/fix-crash-valu-hazard.mir  |  54 ++++++++
 3 files changed, 190 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/CodeGen/AMDGPU/fix-crash-valu-hazard.ll
 create mode 100644 llvm/test/CodeGen/AMDGPU/fix-crash-valu-hazard.mir

diff --git a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
index 6baef137df5e16..873d18e30a430a 100644
--- a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
@@ -858,9 +858,12 @@ int GCNHazardRecognizer::createsVALUHazard(const MachineInstr &MI) {
   }
 
   if (TII->isFLAT(MI)) {
-    int DataIdx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::vdata);
-    if (AMDGPU::getRegBitWidth(Desc.operands()[DataIdx].RegClass) > 64)
-      return DataIdx;
+    // There is no hazard if the instruction does not use vector regs
+    if (VDataIdx == -1)
+      return -1;
+
+    if (AMDGPU::getRegBitWidth(VDataRCID) > 64)
+      return VDataIdx;
   }
 
   return -1;
diff --git a/llvm/test/CodeGen/AMDGPU/fix-crash-valu-hazard.ll b/llvm/test/CodeGen/AMDGPU/fix-crash-valu-hazard.ll
new file mode 100644
index 00000000000000..7390d2ae33e233
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/fix-crash-valu-hazard.ll
@@ -0,0 +1,130 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=amdgcn -mcpu=gfx942 -verify-machineinstrs < %s | FileCheck -check-prefix=GFX942 %s
+; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -O0 -verify-machineinstrs < %s | FileCheck -check-prefix=GFX90A %s
+; RUN: llc -mtriple=amdgcn -mcpu=gfx90a -O0 -global-isel=true -verify-machineinstrs < %s | FileCheck -check-prefixes=GFX90A-GISEL %s
+
+ at G = global <2 x i32> splat (i32 5)
+
+define amdgpu_ps void @global_load_lds_dword_saddr(ptr addrspace(1) inreg nocapture %gptr, ptr addrspace(3) nocapture %lptr) {
+; GFX942-LABEL: global_load_lds_dword_saddr:
+; GFX942:       ; %bb.0: ; %main_body
+; GFX942-NEXT:    s_getpc_b64 s[2:3]
+; GFX942-NEXT:    s_add_u32 s2, s2, G at gotpcrel32@lo+4
+; GFX942-NEXT:    s_addc_u32 s3, s3, G at gotpcrel32@hi+12
+; GFX942-NEXT:    s_load_dwordx2 s[2:3], s[2:3], 0x0
+; GFX942-NEXT:    v_mov_b32_e32 v1, 0
+; GFX942-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX942-NEXT:    v_mov_b64_e32 v[2:3], s[2:3]
+; GFX942-NEXT:    flat_load_dwordx2 v[4:5], v[2:3]
+; GFX942-NEXT:    v_readfirstlane_b32 s2, v0
+; GFX942-NEXT:    s_mov_b32 m0, s2
+; GFX942-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX942-NEXT:    v_mul_lo_u32 v0, v4, 10
+; GFX942-NEXT:    global_load_lds_dword v1, s[0:1] offset:32 nt
+; GFX942-NEXT:    v_mul_lo_u32 v1, v5, 10
+; GFX942-NEXT:    s_waitcnt vmcnt(0)
+; GFX942-NEXT:    flat_store_dwordx2 v[2:3], v[0:1]
+; GFX942-NEXT:    s_endpgm
+;
+; GFX90A-LABEL: global_load_lds_dword_saddr:
+; GFX90A:       ; %bb.0: ; %main_body
+; GFX90A-NEXT:    v_mov_b32_e32 v1, v0
+; GFX90A-NEXT:    s_mov_b32 s2, s0
+; GFX90A-NEXT:    ; kill: def $sgpr2 killed $sgpr2 def $sgpr2_sgpr3
+; GFX90A-NEXT:    s_mov_b32 s3, s1
+; GFX90A-NEXT:    ; kill: def $sgpr0_sgpr1 killed $sgpr2_sgpr3
+; GFX90A-NEXT:    s_getpc_b64 s[0:1]
+; GFX90A-NEXT:    s_add_u32 s0, s0, G at gotpcrel32@lo+4
+; GFX90A-NEXT:    s_addc_u32 s1, s1, G at gotpcrel32@hi+12
+; GFX90A-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x0
+; GFX90A-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX90A-NEXT:    v_pk_mov_b32 v[2:3], s[0:1], s[0:1] op_sel:[0,1]
+; GFX90A-NEXT:    flat_load_dwordx2 v[2:3], v[2:3]
+; GFX90A-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX90A-NEXT:    v_mov_b32_e32 v0, v3
+; GFX90A-NEXT:    s_mov_b32 s4, 10
+; GFX90A-NEXT:    v_mul_lo_u32 v0, v0, s4
+; GFX90A-NEXT:    ; kill: def $vgpr2 killed $vgpr2 killed $vgpr2_vgpr3 killed $exec
+; GFX90A-NEXT:    v_mul_lo_u32 v2, v2, s4
+; GFX90A-NEXT:    ; implicit-def: $sgpr4
+; GFX90A-NEXT:    ; implicit-def: $sgpr4
+; GFX90A-NEXT:    ; kill: def $vgpr2 killed $vgpr2 def $vgpr2_vgpr3 killed $exec
+; GFX90A-NEXT:    v_mov_b32_e32 v3, v0
+; GFX90A-NEXT:    v_mov_b32_e32 v0, 0
+; GFX90A-NEXT:    ; implicit-def: $sgpr4
+; GFX90A-NEXT:    v_readfirstlane_b32 s4, v1
+; GFX90A-NEXT:    s_mov_b32 m0, s4
+; GFX90A-NEXT:    s_nop 0
+; GFX90A-NEXT:    global_load_dword v0, s[2:3] offset:32 slc lds
+; GFX90A-NEXT:    v_pk_mov_b32 v[0:1], s[0:1], s[0:1] op_sel:[0,1]
+; GFX90A-NEXT:    s_waitcnt vmcnt(0)
+; GFX90A-NEXT:    flat_store_dwordx2 v[0:1], v[2:3]
+; GFX90A-NEXT:    s_endpgm
+;
+; GFX90A-GISEL-LABEL: global_load_lds_dword_saddr:
+; GFX90A-GISEL:       ; %bb.0: ; %main_body
+; GFX90A-GISEL-NEXT:    s_mov_b32 s2, s0
+; GFX90A-GISEL-NEXT:    ; kill: def $sgpr2 killed $sgpr2 def $sgpr2_sgpr3
+; GFX90A-GISEL-NEXT:    s_mov_b32 s3, s1
+; GFX90A-GISEL-NEXT:    s_mov_b32 s4, 10
+; GFX90A-GISEL-NEXT:    s_getpc_b64 s[0:1]
+; GFX90A-GISEL-NEXT:    s_add_u32 s0, s0, G at gotpcrel32@lo+4
+; GFX90A-GISEL-NEXT:    s_addc_u32 s1, s1, G at gotpcrel32@hi+12
+; GFX90A-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x0
+; GFX90A-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX90A-GISEL-NEXT:    v_pk_mov_b32 v[2:3], s[0:1], s[0:1] op_sel:[0,1]
+; GFX90A-GISEL-NEXT:    flat_load_dwordx2 v[4:5], v[2:3]
+; GFX90A-GISEL-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX90A-GISEL-NEXT:    v_mov_b32_e32 v2, v4
+; GFX90A-GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GFX90A-GISEL-NEXT:    v_mov_b32_e32 v3, s4
+; GFX90A-GISEL-NEXT:    v_mul_lo_u32 v2, v2, v3
+; GFX90A-GISEL-NEXT:    v_mov_b32_e32 v3, s4
+; GFX90A-GISEL-NEXT:    v_mul_lo_u32 v1, v1, v3
+; GFX90A-GISEL-NEXT:    ; kill: def $vgpr2 killed $vgpr2 def $vgpr2_vgpr3 killed $exec
+; GFX90A-GISEL-NEXT:    v_mov_b32_e32 v3, v1
+; GFX90A-GISEL-NEXT:    v_readfirstlane_b32 s4, v0
+; GFX90A-GISEL-NEXT:    s_mov_b32 m0, s4
+; GFX90A-GISEL-NEXT:    v_mov_b32_e32 v0, 0
+; GFX90A-GISEL-NEXT:    global_load_dword v0, s[2:3] offset:32 slc lds
+; GFX90A-GISEL-NEXT:    v_pk_mov_b32 v[0:1], s[0:1], s[0:1] op_sel:[0,1]
+; GFX90A-GISEL-NEXT:    s_waitcnt vmcnt(0)
+; GFX90A-GISEL-NEXT:    flat_store_dwordx2 v[0:1], v[2:3]
+; GFX90A-GISEL-NEXT:    s_endpgm
+; GISEL-LABEL: global_load_lds_dword_saddr:
+; GISEL:       ; %bb.0: ; %main_body
+; GISEL-NEXT:    s_mov_b32 s2, s0
+; GISEL-NEXT:    ; kill: def $sgpr2 killed $sgpr2 def $sgpr2_sgpr3
+; GISEL-NEXT:    s_mov_b32 s3, s1
+; GISEL-NEXT:    s_mov_b32 s4, 10
+; GISEL-NEXT:    s_getpc_b64 s[0:1]
+; GISEL-NEXT:    s_add_u32 s0, s0, G at gotpcrel32@lo+4
+; GISEL-NEXT:    s_addc_u32 s1, s1, G at gotpcrel32@hi+12
+; GISEL-NEXT:    s_load_dwordx2 s[0:1], s[0:1], 0x0
+; GISEL-NEXT:    s_waitcnt lgkmcnt(0)
+; GISEL-NEXT:    v_pk_mov_b32 v[2:3], s[0:1], s[0:1] op_sel:[0,1]
+; GISEL-NEXT:    flat_load_dwordx2 v[4:5], v[2:3]
+; GISEL-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; GISEL-NEXT:    v_mov_b32_e32 v2, v4
+; GISEL-NEXT:    v_mov_b32_e32 v1, v5
+; GISEL-NEXT:    v_mov_b32_e32 v3, s4
+; GISEL-NEXT:    v_mul_lo_u32 v2, v2, v3
+; GISEL-NEXT:    v_mov_b32_e32 v3, s4
+; GISEL-NEXT:    v_mul_lo_u32 v1, v1, v3
+; GISEL-NEXT:    ; kill: def $vgpr2 killed $vgpr2 def $vgpr2_vgpr3 killed $exec
+; GISEL-NEXT:    v_mov_b32_e32 v3, v1
+; GISEL-NEXT:    v_readfirstlane_b32 s4, v0
+; GISEL-NEXT:    s_mov_b32 m0, s4
+; GISEL-NEXT:    v_mov_b32_e32 v0, 0
+; GISEL-NEXT:    global_load_dword v0, s[2:3] offset:32 slc lds
+; GISEL-NEXT:    v_pk_mov_b32 v[0:1], s[0:1], s[0:1] op_sel:[0,1]
+; GISEL-NEXT:    s_waitcnt vmcnt(0)
+; GISEL-NEXT:    flat_store_dwordx2 v[0:1], v[2:3]
+; GISEL-NEXT:    s_endpgm
+main_body:
+  %LGV = load <2 x i32>, ptr @G, align 8
+  %B = mul <2 x i32> %LGV, splat (i32 10)
+  call void @llvm.amdgcn.global.load.lds(ptr addrspace(1) %gptr, ptr addrspace(3) %lptr, i32 4, i32 32, i32 2)
+  store <2 x i32> %B, ptr @G, align 8
+  ret void
+}
diff --git a/llvm/test/CodeGen/AMDGPU/fix-crash-valu-hazard.mir b/llvm/test/CodeGen/AMDGPU/fix-crash-valu-hazard.mir
new file mode 100644
index 00000000000000..6c1493e546f990
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/fix-crash-valu-hazard.mir
@@ -0,0 +1,54 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=amdgcn -mcpu=gfx942 -verify-machineinstrs -run-pass post-RA-hazard-rec -o - %s | FileCheck %s
+
+--- |
+  @G = global <2 x i32> splat (i32 5)
+
+  define amdgpu_ps void @global_load_lds_dword_saddr(ptr addrspace(1) inreg nocapture %gptr, ptr addrspace(3) nocapture %lptr) #0 {
+  main_body:
+    %LGV = load <2 x i32>, ptr @G, align 8
+    %B = mul <2 x i32> %LGV, splat (i32 10)
+    call void @llvm.amdgcn.global.load.lds(ptr addrspace(1) %gptr, ptr addrspace(3) %lptr, i32 4, i32 32, i32 2)
+    store <2 x i32> %B, ptr @G, align 8
+    ret void
+  }
+
+  attributes #0 = { "amdgpu-memory-bound"="true" "amdgpu-wave-limiter"="true" "target-cpu"="gfx942" }
+
+...
+---
+name:            global_load_lds_dword_saddr
+noVRegs:         true
+body:             |
+  bb.0.main_body:
+    liveins: $sgpr0, $sgpr1, $vgpr0
+
+    ; CHECK-LABEL: name: global_load_lds_dword_saddr
+    ; CHECK: liveins: $sgpr0, $sgpr1, $vgpr0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: renamable $sgpr2_sgpr3 = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @G, target-flags(amdgpu-gotprel32-hi) @G, implicit-def dead $scc
+    ; CHECK-NEXT: renamable $sgpr2_sgpr3 = S_LOAD_DWORDX2_IMM killed renamable $sgpr2_sgpr3, 0, 0 :: (dereferenceable invariant load (s64) from got, addrspace 4)
+    ; CHECK-NEXT: renamable $vgpr1 = V_MOV_B32_e32 0, implicit $exec
+    ; CHECK-NEXT: renamable $vgpr2_vgpr3 = COPY killed renamable $sgpr2_sgpr3
+    ; CHECK-NEXT: renamable $vgpr4_vgpr5 = FLAT_LOAD_DWORDX2 renamable $vgpr2_vgpr3, 0, 0, implicit $exec, implicit $flat_scr :: (dereferenceable load (s64) from @G)
+    ; CHECK-NEXT: renamable $sgpr2 = V_READFIRSTLANE_B32 killed $vgpr0, implicit $exec
+    ; CHECK-NEXT: $m0 = S_MOV_B32 killed renamable $sgpr2
+    ; CHECK-NEXT: S_NOP 0
+    ; CHECK-NEXT: GLOBAL_LOAD_LDS_DWORD_SADDR killed $sgpr0_sgpr1, killed $vgpr1, 32, 2, implicit $m0, implicit $exec :: (load (s32) from `ptr addrspace(1) poison` + 32, align 1, addrspace 1), (store (s32) into %ir.lptr + 32, addrspace 3)
+    ; CHECK-NEXT: renamable $vgpr1 = V_MUL_LO_U32_e64 $vgpr5, 10, implicit $exec
+    ; CHECK-NEXT: renamable $vgpr0 = V_MUL_LO_U32_e64 killed $vgpr4, 10, implicit $exec
+    ; CHECK-NEXT: FLAT_STORE_DWORDX2 killed renamable $vgpr2_vgpr3, killed renamable $vgpr0_vgpr1, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64) into @G)
+    ; CHECK-NEXT: S_ENDPGM 0
+    renamable $sgpr2_sgpr3 = SI_PC_ADD_REL_OFFSET target-flags(amdgpu-gotprel32-lo) @G, target-flags(amdgpu-gotprel32-hi) @G, implicit-def dead $scc
+    renamable $sgpr2_sgpr3 = S_LOAD_DWORDX2_IMM killed renamable $sgpr2_sgpr3, 0, 0 :: (dereferenceable invariant load (s64) from got, addrspace 4)
+    renamable $vgpr1 = V_MOV_B32_e32 0, implicit $exec
+    renamable $vgpr2_vgpr3 = COPY killed renamable $sgpr2_sgpr3
+    renamable $vgpr4_vgpr5 = FLAT_LOAD_DWORDX2 renamable $vgpr2_vgpr3, 0, 0, implicit $exec, implicit $flat_scr :: (dereferenceable load (s64) from @G)
+    renamable $sgpr2 = V_READFIRSTLANE_B32 killed $vgpr0, implicit $exec
+    $m0 = S_MOV_B32 killed renamable $sgpr2
+    GLOBAL_LOAD_LDS_DWORD_SADDR killed $sgpr0_sgpr1, killed $vgpr1, 32, 2, implicit $m0, implicit $exec :: (load (s32) from `ptr addrspace(1) poison` + 32, align 1, addrspace 1), (store (s32) into %ir.lptr + 32, addrspace 3)
+    renamable $vgpr1 = V_MUL_LO_U32_e64 $vgpr5, 10, implicit $exec
+    renamable $vgpr0 = V_MUL_LO_U32_e64 killed $vgpr4, 10, implicit $exec
+    FLAT_STORE_DWORDX2 killed renamable $vgpr2_vgpr3, killed renamable $vgpr0_vgpr1, 0, 0, implicit $exec, implicit $flat_scr :: (store (s64) into @G)
+    S_ENDPGM 0
+...



More information about the llvm-commits mailing list