Skip to content

Commit 58dffde

Browse files
authored
[AMDGPU] Prevent GFX11 VALU Hazard Wait merging into terminators (#214935)
Fix an issue where a pending wait would be moved into the block terminators causing a validation error. Flush all pending waits and exit optimization loop when reaching first terminator within a block.
1 parent 2b44692 commit 58dffde

2 files changed

Lines changed: 61 additions & 5 deletions

File tree

llvm/lib/Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -478,9 +478,6 @@ class AMDGPUWaitSGPRHazards {
478478
};
479479

480480
for (MachineInstr &MI : MBB) {
481-
if (MI.isMetaInstruction())
482-
continue;
483-
484481
if (MI.getOpcode() == AMDGPU::S_WAITCNT_DEPCTR &&
485482
(MI.getOperand(0).getImm() & ConstantMaskBits) ==
486483
ConstantMaskBits) {
@@ -500,12 +497,20 @@ class AMDGPUWaitSGPRHazards {
500497
continue;
501498
}
502499

503-
// Do not optimize over branches
504-
if (PrevWait && (MI.isCall() || MI.isReturn() || MI.isBranch())) {
500+
// Do not optimize over branches or terminators
501+
if (PrevWait && (MI.isCall() || MI.isReturn() || MI.isBranch() ||
502+
MI.isTerminator())) {
505503
PrevWait->moveBefore(&MI);
506504
PrevWait = nullptr;
507505
Changed = true;
508506
}
507+
if (MI.isTerminator())
508+
break;
509+
510+
// Note: test for meta instructions after terminators.
511+
// Required to handle terminator meta instruction.
512+
if (MI.isMetaInstruction())
513+
continue;
509514

510515
const bool IsVALU = SIInstrInfo::isVALU(MI, /*AllowLDSDMA=*/false);
511516
const bool IsSALU = SIInstrInfo::isSALU(MI);

llvm/test/CodeGen/AMDGPU/valu-mask-write-hazard.mir

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
define amdgpu_gs void @mask_hazard_optimize1() { ret void }
6161
define amdgpu_gs void @mask_hazard_optimize2() { ret void }
6262
define amdgpu_gs void @mask_hazard_optimize3() { ret void }
63+
define amdgpu_gs void @mask_hazard_optimize_terminators() { ret void }
6364
...
6465

6566
---
@@ -1268,3 +1269,53 @@ body: |
12681269
$vgpr14 = V_CNDMASK_B32_e32 $sgpr49, killed $vgpr14, implicit killed $vcc, implicit $exec
12691270
$vgpr20 = V_ADD_U32_e32 $sgpr54, $vgpr16, implicit $exec
12701271
...
1272+
1273+
---
1274+
name: mask_hazard_optimize_terminators
1275+
body: |
1276+
; GFX11-LABEL: name: mask_hazard_optimize_terminators
1277+
; GFX11: bb.0:
1278+
; GFX11-NEXT: successors: %bb.1(0x80000000)
1279+
; GFX11-NEXT: {{ $}}
1280+
; GFX11-NEXT: $vgpr3 = V_CNDMASK_B32_e32 $vgpr1, $vgpr2, implicit $vcc, implicit $exec
1281+
; GFX11-NEXT: V_CMP_NE_U32_e32 0, $vgpr5, implicit-def $vcc, implicit $exec
1282+
; GFX11-NEXT: $sgpr4 = S_MOV_B32 $sgpr1
1283+
; GFX11-NEXT: $sgpr5 = S_MOV_B32 $sgpr2
1284+
; GFX11-NEXT: S_WAITCNT_DEPCTR .VaVcc_0
1285+
; GFX11-NEXT: $sgpr6 = S_MOV_B32_term $sgpr4
1286+
; GFX11-NEXT: $sgpr7 = S_MOV_B32_term $sgpr5
1287+
; GFX11-NEXT: S_BRANCH %bb.1
1288+
; GFX11-NEXT: {{ $}}
1289+
; GFX11-NEXT: bb.1:
1290+
; GFX11-NEXT: $vgpr4 = V_CNDMASK_B32_e32 $vgpr1, $vgpr2, implicit $vcc, implicit $exec
1291+
; GFX11-NEXT: S_ENDPGM 0
1292+
;
1293+
; GFX12-LABEL: name: mask_hazard_optimize_terminators
1294+
; GFX12: bb.0:
1295+
; GFX12-NEXT: successors: %bb.1(0x80000000)
1296+
; GFX12-NEXT: {{ $}}
1297+
; GFX12-NEXT: $vgpr3 = V_CNDMASK_B32_e32 $vgpr1, $vgpr2, implicit $vcc, implicit $exec
1298+
; GFX12-NEXT: V_CMP_NE_U32_e32 0, $vgpr5, implicit-def $vcc, implicit $exec
1299+
; GFX12-NEXT: $sgpr4 = S_MOV_B32 $sgpr1
1300+
; GFX12-NEXT: $sgpr5 = S_MOV_B32 $sgpr2
1301+
; GFX12-NEXT: $sgpr6 = S_MOV_B32_term $sgpr4
1302+
; GFX12-NEXT: $sgpr7 = S_MOV_B32_term $sgpr5
1303+
; GFX12-NEXT: S_BRANCH %bb.1
1304+
; GFX12-NEXT: {{ $}}
1305+
; GFX12-NEXT: bb.1:
1306+
; GFX12-NEXT: S_WAITCNT_DEPCTR .VaVcc_0
1307+
; GFX12-NEXT: $vgpr4 = V_CNDMASK_B32_e32 $vgpr1, $vgpr2, implicit $vcc, implicit $exec
1308+
; GFX12-NEXT: S_ENDPGM 0
1309+
bb.0:
1310+
$vgpr3 = V_CNDMASK_B32_e32 $vgpr1, $vgpr2, implicit $vcc, implicit $exec
1311+
V_CMP_NE_U32_e32 0, $vgpr5, implicit-def $vcc, implicit $exec
1312+
$sgpr4 = S_MOV_B32 $sgpr1
1313+
$sgpr5 = S_MOV_B32 $sgpr2
1314+
$sgpr6 = S_MOV_B32_term $sgpr4
1315+
$sgpr7 = S_MOV_B32_term $sgpr5
1316+
S_BRANCH %bb.1
1317+
1318+
bb.1:
1319+
$vgpr4 = V_CNDMASK_B32_e32 $vgpr1, $vgpr2, implicit $vcc, implicit $exec
1320+
S_ENDPGM 0
1321+
...

0 commit comments

Comments
 (0)