| # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6 | |
| # RUN: llc -mtriple=amdgpu12.50 -run-pass=machine-scheduler -amdgpu-sched-strategy=coexec -verify-misched %s -o - | FileCheck -check-prefix=CHECK %s | |
| # Tests for the multi-shadow hazard: WMMA + TRANS + VALU cannot all execute | |
| # simultaneously. When both a WMMA and a TRANS instruction are actively | |
| # executing (their shadows overlap), a subsequent VALU instruction must stall | |
| # until at least one of the shadows clears. | |
| # | |
| # Uses V_WMMA_F32_16X16X32_BF16 which has pattern 0EIIEEIIV (9-cycle window, | |
| # 8-cycle occupancy). | |
| # | |
| # Co-execution window slots: | |
| # Stage: 0 1 2 3 4 5 6 7 8 | |
| # Slot: E0 E I I E E I I V | |
| # | |
| # When TRANS is issued at stage 1 (E slot), it creates a 2-cycle shadow. | |
| # A subsequent VALU at stage 2 cannot execute because both WMMA and TRANS | |
| # shadows are active - must wait for TRANS shadow to clear. | |
| --- | | |
| define void @wmma_trans_valu() #0 { ret void } | |
| attributes #0 = { "amdgpu-waves-per-eu"="1,1" } | |
| ... | |
| # Test: WMMA -> TRANS -> VALU with dependency chain | |
| # TRANS uses WMMA result, VALU uses TRANS result. The dependency forces order. | |
| # The scheduler inserts SALU and COPY between to cover the gap. | |
| --- | |
| name: wmma_trans_valu | |
| tracksRegLiveness: true | |
| body: | | |
| ; CHECK-LABEL: name: wmma_trans_valu | |
| ; CHECK: bb.0: | |
| ; CHECK-NEXT: successors: %bb.1(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[DEF:%[0-9]+]]:vreg_256_align2 = IMPLICIT_DEF | |
| ; CHECK-NEXT: [[DEF1:%[0-9]+]]:vreg_256_align2 = IMPLICIT_DEF | |
| ; CHECK-NEXT: [[DEF2:%[0-9]+]]:vreg_256_align2 = IMPLICIT_DEF | |
| ; CHECK-NEXT: [[DEF3:%[0-9]+]]:sreg_32 = IMPLICIT_DEF | |
| ; CHECK-NEXT: [[DEF4:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF | |
| ; CHECK-NEXT: S_BRANCH %bb.1 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.1: | |
| ; CHECK-NEXT: dead early-clobber %5:vreg_256_align2 = V_WMMA_F32_16X16X32_BF16_w32_twoaddr [[DEF]], [[DEF1]], 8, [[DEF2]], 0, 0, 0, 0, implicit $exec | |
| ; CHECK-NEXT: SCHED_BARRIER 1 | |
| ; CHECK-NEXT: [[S_ADD_I32_:%[0-9]+]]:sreg_32 = S_ADD_I32 [[DEF3]], [[DEF3]], implicit-def dead $scc | |
| ; CHECK-NEXT: [[V_EXP_F32_e32_:%[0-9]+]]:vgpr_32 = nofpexcept V_EXP_F32_e32 [[DEF4]], implicit $mode, implicit $exec | |
| ; CHECK-NEXT: [[V_ADD_F32_e32_:%[0-9]+]]:vgpr_32 = nofpexcept V_ADD_F32_e32 [[V_EXP_F32_e32_]], [[V_EXP_F32_e32_]], implicit $mode, implicit $exec | |
| ; CHECK-NEXT: S_ENDPGM 0, implicit [[DEF4]], implicit [[V_EXP_F32_e32_]], implicit [[V_ADD_F32_e32_]], implicit [[S_ADD_I32_]] | |
| bb.0: | |
| successors: %bb.1 | |
| %0:vreg_256_align2 = IMPLICIT_DEF | |
| %1:vreg_256_align2 = IMPLICIT_DEF | |
| %2:vreg_256_align2 = IMPLICIT_DEF | |
| %3:sreg_32 = IMPLICIT_DEF | |
| %4:vgpr_32 = IMPLICIT_DEF | |
| S_BRANCH %bb.1 | |
| bb.1: | |
| early-clobber %5:vreg_256_align2 = V_WMMA_F32_16X16X32_BF16_w32_twoaddr %0, %1, 8, %2, 0, 0, 0, 0, implicit $exec | |
| %6:vgpr_32 = nofpexcept V_EXP_F32_e32 %4, implicit $mode, implicit $exec | |
| SCHED_BARRIER 1 | |
| %7:vgpr_32 = nofpexcept V_ADD_F32_e32 %6, %6, implicit $mode, implicit $exec | |
| %8:sreg_32 = S_ADD_I32 %3, %3, implicit-def dead $scc | |
| S_ENDPGM 0, implicit %4, implicit %6, implicit %7, implicit %8 | |
| ... | |
| ... |