[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