blob: 56b37b6286da4b3c4f2894d28c7f167c7aa8d405 [file] [edit]
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
# RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -run-pass=pipeliner -pipeliner-force-ii=12 %s -o - | FileCheck %s
# RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -passes=pipeliner -pipeliner-force-ii=12 %s -o - | FileCheck %s
# Two independent recurrences (a sum and a product) must be carried across the stage
# boundary without being swapped: each accumulator's kernel result has to flow through
# its own epilog PHI and drain op into its own store.
---
name: swp_amdgpu_pipeline_epilog_phi
tracksRegLiveness: true
isSSA: true
liveins:
- { reg: '$sgpr4_sgpr5' }
machineFunctionInfo:
isEntryFunction: true
argumentInfo:
kernargSegmentPtr: { reg: '$sgpr4_sgpr5' }
body: |
; CHECK-LABEL: name: swp_amdgpu_pipeline_epilog_phi
; CHECK: bb.0:
; CHECK-NEXT: successors: %bb.3(0x80000000)
; CHECK-NEXT: liveins: $sgpr4_sgpr5
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr_64(p4) = COPY $sgpr4_sgpr5
; CHECK-NEXT: [[S_LOAD_DWORDX4_IMM:%[0-9]+]]:sgpr_128 = S_LOAD_DWORDX4_IMM [[COPY]](p4), 0, 0 :: (dereferenceable invariant load (s128), addrspace 4)
; CHECK-NEXT: [[S_LOAD_DWORD_IMM:%[0-9]+]]:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM [[COPY]](p4), 16, 0 :: (dereferenceable invariant load (s32), align 16, addrspace 4)
; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64_xexec_xnull = REG_SEQUENCE [[S_LOAD_DWORDX4_IMM]].sub0, %subreg.sub0, [[S_LOAD_DWORDX4_IMM]].sub1, %subreg.sub1
; CHECK-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64_xexec_xnull = REG_SEQUENCE [[S_LOAD_DWORDX4_IMM]].sub2, %subreg.sub0, [[S_LOAD_DWORDX4_IMM]].sub3, %subreg.sub1
; CHECK-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 0
; CHECK-NEXT: [[AV_MOV_:%[0-9]+]]:vgpr_32 = AV_MOV_B32_IMM_PSEUDO 1065353216, implicit $exec
; CHECK-NEXT: [[AV_MOV_1:%[0-9]+]]:vgpr_32 = AV_MOV_B32_IMM_PSEUDO 0, implicit $exec
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.3:
; CHECK-NEXT: successors: %bb.4(0x80000000), %bb.5(0x00000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[S_ASHR_I32_:%[0-9]+]]:sreg_32_xm0 = S_ASHR_I32 [[S_MOV_B32_]], 31, implicit-def dead $scc
; CHECK-NEXT: [[REG_SEQUENCE2:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[S_MOV_B32_]], %subreg.sub0, [[S_ASHR_I32_]], %subreg.sub1
; CHECK-NEXT: [[S_LSHL_B64_:%[0-9]+]]:sreg_64 = S_LSHL_B64 [[REG_SEQUENCE2]], 2, implicit-def dead $scc
; CHECK-NEXT: [[S_ADD_U32_:%[0-9]+]]:sreg_32 = S_ADD_U32 [[REG_SEQUENCE]].sub0, [[S_LSHL_B64_]].sub0, implicit-def $scc
; CHECK-NEXT: [[S_ADDC_U32_:%[0-9]+]]:sreg_32 = S_ADDC_U32 [[REG_SEQUENCE]].sub1, [[S_LSHL_B64_]].sub1, implicit-def $scc, implicit $scc
; CHECK-NEXT: [[REG_SEQUENCE3:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[S_ADD_U32_]], %subreg.sub0, [[S_ADDC_U32_]], %subreg.sub1
; CHECK-NEXT: [[S_ADD_U32_1:%[0-9]+]]:sreg_32 = S_ADD_U32 [[REG_SEQUENCE1]].sub0, [[S_LSHL_B64_]].sub0, implicit-def $scc
; CHECK-NEXT: [[S_ADDC_U32_1:%[0-9]+]]:sreg_32 = S_ADDC_U32 [[REG_SEQUENCE1]].sub1, [[S_LSHL_B64_]].sub1, implicit-def $scc, implicit $scc
; CHECK-NEXT: [[REG_SEQUENCE4:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[S_ADD_U32_1]], %subreg.sub0, [[S_ADDC_U32_1]], %subreg.sub1
; CHECK-NEXT: [[S_LOAD_DWORD_IMM1:%[0-9]+]]:sgpr_32 = S_LOAD_DWORD_IMM [[REG_SEQUENCE3]], 0, 0 :: (load (s32), addrspace 1)
; CHECK-NEXT: [[S_LOAD_DWORD_IMM2:%[0-9]+]]:sgpr_32 = S_LOAD_DWORD_IMM [[REG_SEQUENCE4]], 0, 0 :: (load (s32), addrspace 1)
; CHECK-NEXT: [[S_ADD_I32_:%[0-9]+]]:sreg_32 = S_ADD_I32 [[S_MOV_B32_]], 1, implicit-def dead $scc
; CHECK-NEXT: S_CMP_LT_I32 [[S_ADD_I32_]], [[S_LOAD_DWORD_IMM]], implicit-def $scc
; CHECK-NEXT: S_CBRANCH_SCC0 %bb.5, implicit $scc
; CHECK-NEXT: S_BRANCH %bb.4
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.4:
; CHECK-NEXT: successors: %bb.5(0x40000000), %bb.4(0x40000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[PHI:%[0-9]+]]:sreg_32 = PHI [[S_ADD_I32_]], %bb.3, %46, %bb.4
; CHECK-NEXT: [[PHI1:%[0-9]+]]:vgpr_32 = PHI [[AV_MOV_1]], %bb.3, %51, %bb.4
; CHECK-NEXT: [[PHI2:%[0-9]+]]:vgpr_32 = PHI [[AV_MOV_]], %bb.3, %49, %bb.4
; CHECK-NEXT: [[PHI3:%[0-9]+]]:sgpr_32 = PHI [[S_LOAD_DWORD_IMM1]], %bb.3, %50, %bb.4
; CHECK-NEXT: [[PHI4:%[0-9]+]]:sgpr_32 = PHI [[S_LOAD_DWORD_IMM2]], %bb.3, %48, %bb.4
; CHECK-NEXT: [[S_ASHR_I32_1:%[0-9]+]]:sreg_32_xm0 = S_ASHR_I32 [[PHI]], 31, implicit-def dead $scc
; CHECK-NEXT: [[REG_SEQUENCE5:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[PHI]], %subreg.sub0, [[S_ASHR_I32_1]], %subreg.sub1
; CHECK-NEXT: [[S_LSHL_B64_1:%[0-9]+]]:sreg_64 = S_LSHL_B64 [[REG_SEQUENCE5]], 2, implicit-def dead $scc
; CHECK-NEXT: [[S_ADD_U32_2:%[0-9]+]]:sreg_32 = S_ADD_U32 [[REG_SEQUENCE]].sub0, [[S_LSHL_B64_1]].sub0, implicit-def $scc
; CHECK-NEXT: [[S_ADDC_U32_2:%[0-9]+]]:sreg_32 = S_ADDC_U32 [[REG_SEQUENCE]].sub1, [[S_LSHL_B64_1]].sub1, implicit-def $scc, implicit $scc
; CHECK-NEXT: [[S_ADD_U32_3:%[0-9]+]]:sreg_32 = S_ADD_U32 [[REG_SEQUENCE1]].sub0, [[S_LSHL_B64_1]].sub0, implicit-def $scc
; CHECK-NEXT: [[REG_SEQUENCE6:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[S_ADD_U32_2]], %subreg.sub0, [[S_ADDC_U32_2]], %subreg.sub1
; CHECK-NEXT: [[S_ADDC_U32_3:%[0-9]+]]:sreg_32 = S_ADDC_U32 [[REG_SEQUENCE1]].sub1, [[S_LSHL_B64_1]].sub1, implicit-def $scc, implicit $scc
; CHECK-NEXT: [[S_ADD_I32_1:%[0-9]+]]:sreg_32 = S_ADD_I32 [[PHI]], 1, implicit-def dead $scc
; CHECK-NEXT: [[REG_SEQUENCE7:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[S_ADD_U32_3]], %subreg.sub0, [[S_ADDC_U32_3]], %subreg.sub1
; CHECK-NEXT: [[S_LOAD_DWORD_IMM3:%[0-9]+]]:sgpr_32 = S_LOAD_DWORD_IMM [[REG_SEQUENCE7]], 0, 0 :: (load (s32), addrspace 1)
; CHECK-NEXT: [[V_MUL_F32_e32_:%[0-9]+]]:vgpr_32 = nofpexcept V_MUL_F32_e32 [[PHI4]], [[PHI2]], implicit $mode, implicit $exec
; CHECK-NEXT: [[S_LOAD_DWORD_IMM4:%[0-9]+]]:sgpr_32 = S_LOAD_DWORD_IMM [[REG_SEQUENCE6]], 0, 0 :: (load (s32), addrspace 1)
; CHECK-NEXT: [[V_ADD_F32_e32_:%[0-9]+]]:vgpr_32 = nofpexcept V_ADD_F32_e32 [[PHI3]], [[PHI1]], implicit $mode, implicit $exec
; CHECK-NEXT: S_CMP_LT_I32 [[S_ADD_I32_1]], [[S_LOAD_DWORD_IMM]], implicit-def $scc
; CHECK-NEXT: S_CBRANCH_SCC1 %bb.4, implicit $scc
; CHECK-NEXT: S_BRANCH %bb.5
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.5:
; CHECK-NEXT: successors: %bb.2(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[PHI5:%[0-9]+]]:vgpr_32 = PHI [[AV_MOV_1]], %bb.3, [[V_ADD_F32_e32_]], %bb.4
; CHECK-NEXT: [[PHI6:%[0-9]+]]:vgpr_32 = PHI [[AV_MOV_]], %bb.3, [[V_MUL_F32_e32_]], %bb.4
; CHECK-NEXT: [[PHI7:%[0-9]+]]:sgpr_32 = PHI [[S_LOAD_DWORD_IMM1]], %bb.3, [[S_LOAD_DWORD_IMM4]], %bb.4
; CHECK-NEXT: [[PHI8:%[0-9]+]]:sgpr_32 = PHI [[S_LOAD_DWORD_IMM2]], %bb.3, [[S_LOAD_DWORD_IMM3]], %bb.4
; CHECK-NEXT: [[V_ADD_F32_e32_1:%[0-9]+]]:vgpr_32 = nofpexcept V_ADD_F32_e32 [[PHI7]], [[PHI5]], implicit $mode, implicit $exec
; CHECK-NEXT: [[V_MUL_F32_e32_1:%[0-9]+]]:vgpr_32 = nofpexcept V_MUL_F32_e32 [[PHI8]], [[PHI6]], implicit $mode, implicit $exec
; CHECK-NEXT: S_BRANCH %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: [[AV_MOV_2:%[0-9]+]]:vgpr_32 = AV_MOV_B32_IMM_PSEUDO 0, implicit $exec
; CHECK-NEXT: GLOBAL_STORE_DWORD_SADDR [[AV_MOV_2]], [[V_ADD_F32_e32_1]], [[REG_SEQUENCE]], 0, 0, implicit $exec :: (store (s32), addrspace 1)
; CHECK-NEXT: GLOBAL_STORE_DWORD_SADDR [[AV_MOV_2]], [[V_MUL_F32_e32_1]], [[REG_SEQUENCE1]], 0, 0, implicit $exec :: (store (s32), addrspace 1)
; CHECK-NEXT: S_ENDPGM 0
bb.0:
liveins: $sgpr4_sgpr5
%0:sgpr_64(p4) = COPY $sgpr4_sgpr5
%1:sgpr_128 = S_LOAD_DWORDX4_IMM %0(p4), 0, 0 :: (dereferenceable invariant load (s128), addrspace 4)
%2:sreg_32_xm0_xexec = S_LOAD_DWORD_IMM %0(p4), 16, 0 :: (dereferenceable invariant load (s32), align 16, addrspace 4)
%3:sreg_64_xexec_xnull = REG_SEQUENCE %1.sub0, %subreg.sub0, %1.sub1, %subreg.sub1
%4:sreg_64_xexec_xnull = REG_SEQUENCE %1.sub2, %subreg.sub0, %1.sub3, %subreg.sub1
%5:sreg_32 = S_MOV_B32 0
%6:vgpr_32 = AV_MOV_B32_IMM_PSEUDO 1065353216, implicit $exec
%7:vgpr_32 = AV_MOV_B32_IMM_PSEUDO 0, implicit $exec
bb.1:
successors: %bb.2, %bb.1
%8:sreg_32 = PHI %5, %bb.0, %9, %bb.1
%10:vgpr_32 = PHI %7, %bb.0, %11, %bb.1
%12:vgpr_32 = PHI %6, %bb.0, %13, %bb.1
%14:sreg_32_xm0 = S_ASHR_I32 %8, 31, implicit-def dead $scc
%15:sreg_64 = REG_SEQUENCE %8, %subreg.sub0, %14, %subreg.sub1
%16:sreg_64 = S_LSHL_B64 killed %15, 2, implicit-def dead $scc
%17:sreg_32 = S_ADD_U32 %3.sub0, %16.sub0, implicit-def $scc
%18:sreg_32 = S_ADDC_U32 %3.sub1, %16.sub1, implicit-def $scc, implicit $scc
%19:sreg_64 = REG_SEQUENCE %17, %subreg.sub0, %18, %subreg.sub1
%20:sreg_32 = S_ADD_U32 %4.sub0, %16.sub0, implicit-def $scc
%21:sreg_32 = S_ADDC_U32 %4.sub1, %16.sub1, implicit-def $scc, implicit $scc
%22:sreg_64 = REG_SEQUENCE %20, %subreg.sub0, %21, %subreg.sub1
%23:sgpr_32 = S_LOAD_DWORD_IMM killed %19, 0, 0 :: (load (s32), addrspace 1)
%24:sgpr_32 = S_LOAD_DWORD_IMM killed %22, 0, 0 :: (load (s32), addrspace 1)
%11:vgpr_32 = nofpexcept V_ADD_F32_e32 %23, %10, implicit $mode, implicit $exec
%13:vgpr_32 = nofpexcept V_MUL_F32_e32 %24, %12, implicit $mode, implicit $exec
%9:sreg_32 = S_ADD_I32 %8, 1, implicit-def dead $scc
S_CMP_LT_I32 %9, %2, implicit-def $scc
S_CBRANCH_SCC1 %bb.1, implicit $scc
S_BRANCH %bb.2
bb.2:
%25:vgpr_32 = AV_MOV_B32_IMM_PSEUDO 0, implicit $exec
GLOBAL_STORE_DWORD_SADDR %25, %11, %3, 0, 0, implicit $exec :: (store (s32), addrspace 1)
GLOBAL_STORE_DWORD_SADDR %25, %13, %4, 0, 0, implicit $exec :: (store (s32), addrspace 1)
S_ENDPGM 0
...