| # RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -run-pass=pipeliner -pipeliner-force-ii=8 %s -o - | FileCheck %s |
| # Verify the generated prolog / steady-state kernel / epilog structure of a pipelined loop. |
| |
| # CHECK-LABEL: name: swp_amdgpu_pipeline_gen_structure |
| |
| # Prolog: peeled first-iteration load, then a guard that skips the kernel to the epilog. |
| # CHECK: bb.3: |
| # CHECK: S_LOAD_DWORD_IMM |
| # CHECK: S_CBRANCH_SCC0 %bb.5 |
| |
| # Steady-state kernel: loop-carried PHIs, with the next-iteration load overlapping the |
| # current-iteration accumulate. |
| # CHECK: bb.4: |
| # CHECK-DAG: {{%[0-9]+}}:sreg_32 = PHI {{%[0-9]+}}, %bb.3, {{%[0-9]+}}, %bb.4 |
| # CHECK-DAG: {{%[0-9]+}}:vgpr_32 = PHI {{%[0-9]+}}, %bb.3, {{%[0-9]+}}, %bb.4 |
| # CHECK-DAG: {{%[0-9]+}}:sgpr_32 = PHI {{%[0-9]+}}, %bb.3, {{%[0-9]+}}, %bb.4 |
| # CHECK: S_LOAD_DWORD_IMM |
| # CHECK: V_ADD_F32_e32 |
| # CHECK: S_CBRANCH_SCC1 %bb.4 |
| |
| # Epilog: drains the final accumulate for the last in-flight iteration. |
| # CHECK: bb.5: |
| # CHECK: {{%[0-9]+}}:vgpr_32 = PHI {{%[0-9]+}}, %bb.3, {{%[0-9]+}}, %bb.4 |
| # CHECK: V_ADD_F32_e32 |
| # CHECK: bb.2: |
| # CHECK: GLOBAL_STORE_DWORD_SADDR |
| # CHECK: S_ENDPGM |
| |
| --- |
| name: swp_amdgpu_pipeline_gen_structure |
| tracksRegLiveness: true |
| isSSA: true |
| liveins: |
| - { reg: '$sgpr4_sgpr5' } |
| machineFunctionInfo: |
| isEntryFunction: true |
| argumentInfo: |
| kernargSegmentPtr: { reg: '$sgpr4_sgpr5' } |
| body: | |
| bb.0: |
| liveins: $sgpr4_sgpr5 |
| |
| %0:sgpr_64(p4) = COPY $sgpr4_sgpr5 |
| %1:sreg_64_xexec_xnull = S_LOAD_DWORDX2_IMM %0(p4), 0, 0 :: (dereferenceable invariant load (s64), align 16, addrspace 4) |
| %2:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM %0(p4), 8, 0 :: (dereferenceable invariant load (s32), align 8, addrspace 4) |
| %3:sreg_32 = S_MOV_B32 0 |
| %4:vgpr_32 = AV_MOV_B32_IMM_PSEUDO 0, implicit $exec |
| |
| bb.1: |
| successors: %bb.2, %bb.1 |
| |
| %5:sreg_32 = PHI %3, %bb.0, %6, %bb.1 |
| %7:vgpr_32 = PHI %4, %bb.0, %8, %bb.1 |
| %9:sreg_32_xm0 = S_ASHR_I32 %5, 31, implicit-def dead $scc |
| %10:sreg_64 = REG_SEQUENCE %5, %subreg.sub0, %9, %subreg.sub1 |
| %11:sreg_64 = S_LSHL_B64 %10, 2, implicit-def dead $scc |
| %12:sreg_32 = S_ADD_U32 %1.sub0, %11.sub0, implicit-def $scc |
| %13:sreg_32 = S_ADDC_U32 %1.sub1, %11.sub1, implicit-def $scc, implicit $scc |
| %14:sreg_64 = REG_SEQUENCE %12, %subreg.sub0, %13, %subreg.sub1 |
| %15:sgpr_32 = S_LOAD_DWORD_IMM %14, 0, 0 :: (load (s32), addrspace 1) |
| %8:vgpr_32 = nofpexcept V_ADD_F32_e32 %15, %7, implicit $mode, implicit $exec |
| %6:sreg_32 = S_ADD_I32 %5, 1, implicit-def dead $scc |
| S_CMP_LT_I32 %6, %2, implicit-def $scc |
| S_CBRANCH_SCC1 %bb.1, implicit $scc |
| S_BRANCH %bb.2 |
| |
| bb.2: |
| %16:vgpr_32 = AV_MOV_B32_IMM_PSEUDO 0, implicit $exec |
| GLOBAL_STORE_DWORD_SADDR %16, %8, %1, 0, 0, implicit $exec :: (store (s32), addrspace 1) |
| S_ENDPGM 0 |
| ... |