| # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6 | |
| # RUN: llc -mtriple=amdgpu9.50 -run-pass=liveintervals,phi-node-elimination -o - %s | FileCheck %s | |
| # RUN: llc -mtriple=amdgpu9.50 \ | |
| # RUN: --passes='require<live-intervals>,phi-node-elimination' -verify-each -o - %s | FileCheck %s | |
| # | |
| # The high lane is dead before the PHI predecessor, but its segment belongs to | |
| # a block appearing later in layout order. It must not be trimmed using the | |
| # low lane's last-use slot. | |
| --- | |
| name: phi_subrange_absent | |
| tracksRegLiveness: true | |
| body: | | |
| ; CHECK-LABEL: name: phi_subrange_absent | |
| ; CHECK: bb.0: | |
| ; CHECK-NEXT: successors: %bb.3(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: S_BRANCH %bb.3 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.1: | |
| ; CHECK-NEXT: successors: %bb.2(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY %1.sub0 | |
| ; CHECK-NEXT: S_BRANCH %bb.2 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.2: | |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[COPY]] | |
| ; CHECK-NEXT: $vgpr0 = COPY [[COPY1]] | |
| ; CHECK-NEXT: S_ENDPGM 0 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.3: | |
| ; CHECK-NEXT: successors: %bb.1(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[V_MOV_B32_e32_]], %subreg.sub0, [[V_MOV_B32_e32_1]], %subreg.sub1 | |
| ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY [[REG_SEQUENCE]].sub1 | |
| ; CHECK-NEXT: $vgpr1 = COPY [[COPY2]] | |
| ; CHECK-NEXT: S_BRANCH %bb.1 | |
| bb.0: | |
| successors: %bb.3 | |
| S_BRANCH %bb.3 | |
| bb.1: | |
| successors: %bb.2 | |
| S_BRANCH %bb.2 | |
| bb.2: | |
| %2:vgpr_32 = PHI %0.sub0, %bb.1 | |
| $vgpr0 = COPY %2 | |
| S_ENDPGM 0 | |
| bb.3: | |
| successors: %bb.1 | |
| %3:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| %4:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| %0:vreg_64 = REG_SEQUENCE %3, %subreg.sub0, %4, %subreg.sub1 | |
| %1:vgpr_32 = COPY %0.sub1 | |
| $vgpr1 = COPY %1 | |
| S_BRANCH %bb.1 | |
| ... | |
| # The high lane's segment ends in an earlier layout block. It needs no trim. | |
| --- | |
| name: phi_subrange_dead_earlier | |
| tracksRegLiveness: true | |
| body: | | |
| ; CHECK-LABEL: name: phi_subrange_dead_earlier | |
| ; CHECK: bb.0: | |
| ; CHECK-NEXT: successors: %bb.1(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[V_MOV_B32_e32_]], %subreg.sub0, [[V_MOV_B32_e32_1]], %subreg.sub1 | |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY [[REG_SEQUENCE]].sub1 | |
| ; CHECK-NEXT: $vgpr1 = COPY [[COPY]] | |
| ; CHECK-NEXT: S_BRANCH %bb.1 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.1: | |
| ; CHECK-NEXT: successors: %bb.2(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[REG_SEQUENCE]].sub0 | |
| ; CHECK-NEXT: S_BRANCH %bb.2 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.2: | |
| ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY [[COPY1]] | |
| ; CHECK-NEXT: $vgpr0 = COPY [[COPY2]] | |
| ; CHECK-NEXT: S_ENDPGM 0 | |
| bb.0: | |
| successors: %bb.1 | |
| %3:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| %4:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| %0:vreg_64 = REG_SEQUENCE %3, %subreg.sub0, %4, %subreg.sub1 | |
| %1:vgpr_32 = COPY %0.sub1 | |
| $vgpr1 = COPY %1 | |
| S_BRANCH %bb.1 | |
| bb.1: | |
| successors: %bb.2 | |
| S_BRANCH %bb.2 | |
| bb.2: | |
| %2:vgpr_32 = PHI %0.sub0, %bb.1 | |
| $vgpr0 = COPY %2 | |
| S_ENDPGM 0 | |
| ... | |
| # Both lanes and the main live range still require normal PHI source trimming. | |
| --- | |
| name: phi_subrange_full_live | |
| tracksRegLiveness: true | |
| body: | | |
| ; CHECK-LABEL: name: phi_subrange_full_live | |
| ; CHECK: bb.0: | |
| ; CHECK-NEXT: successors: %bb.1(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[V_MOV_B32_e32_]], %subreg.sub0, [[V_MOV_B32_e32_1]], %subreg.sub1 | |
| ; CHECK-NEXT: S_BRANCH %bb.1 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.1: | |
| ; CHECK-NEXT: successors: %bb.2(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:vreg_64 = COPY [[REG_SEQUENCE]] | |
| ; CHECK-NEXT: S_BRANCH %bb.2 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.2: | |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vreg_64 = COPY [[COPY]] | |
| ; CHECK-NEXT: $vgpr0_vgpr1 = COPY [[COPY1]] | |
| ; CHECK-NEXT: S_ENDPGM 0 | |
| bb.0: | |
| successors: %bb.1 | |
| %1:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| %0:vreg_64 = REG_SEQUENCE %1, %subreg.sub0, %2, %subreg.sub1 | |
| S_BRANCH %bb.1 | |
| bb.1: | |
| successors: %bb.2 | |
| S_BRANCH %bb.2 | |
| bb.2: | |
| %3:vreg_64 = PHI %0, %bb.1 | |
| $vgpr0_vgpr1 = COPY %3 | |
| S_ENDPGM 0 | |
| ... | |
| # Different PHI source copies read different lanes. Each lane must end at its | |
| # own copy, not at the main range's last use in the predecessor. | |
| --- | |
| name: phi_subrange_separate_uses | |
| tracksRegLiveness: true | |
| body: | | |
| ; CHECK-LABEL: name: phi_subrange_separate_uses | |
| ; CHECK: bb.0: | |
| ; CHECK-NEXT: successors: %bb.1(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[V_MOV_B32_e32_]], %subreg.sub0, [[V_MOV_B32_e32_1]], %subreg.sub1 | |
| ; CHECK-NEXT: S_BRANCH %bb.1 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.1: | |
| ; CHECK-NEXT: successors: %bb.2(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY [[REG_SEQUENCE]].sub0 | |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[REG_SEQUENCE]].sub1 | |
| ; CHECK-NEXT: S_BRANCH %bb.2 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.2: | |
| ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY [[COPY]] | |
| ; CHECK-NEXT: $vgpr0 = COPY [[COPY2]] | |
| ; CHECK-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY [[COPY1]] | |
| ; CHECK-NEXT: $vgpr1 = COPY [[COPY3]] | |
| ; CHECK-NEXT: S_ENDPGM 0 | |
| bb.0: | |
| successors: %bb.1 | |
| %1:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| %0:vreg_64 = REG_SEQUENCE %1, %subreg.sub0, %2, %subreg.sub1 | |
| S_BRANCH %bb.1 | |
| bb.1: | |
| successors: %bb.2 | |
| S_BRANCH %bb.2 | |
| bb.2: | |
| %3:vgpr_32 = PHI %0.sub0, %bb.1 | |
| %4:vgpr_32 = PHI %0.sub1, %bb.1 | |
| $vgpr0 = COPY %3 | |
| $vgpr1 = COPY %4 | |
| S_ENDPGM 0 | |
| ... | |
| # PHIs in two different successor blocks share the source register. Shrinking | |
| # must wait for the whole function's PHIs to be removed. | |
| --- | |
| name: phi_subrange_multiple_successors | |
| tracksRegLiveness: true | |
| body: | | |
| ; CHECK-LABEL: name: phi_subrange_multiple_successors | |
| ; CHECK: bb.0: | |
| ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[V_MOV_B32_e32_]], %subreg.sub0, [[V_MOV_B32_e32_1]], %subreg.sub1 | |
| ; CHECK-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 0 | |
| ; CHECK-NEXT: S_CMP_EQ_U32 [[S_MOV_B32_]], 0, implicit-def $scc | |
| ; CHECK-NEXT: S_CBRANCH_SCC1 %bb.2, implicit $scc | |
| ; CHECK-NEXT: S_BRANCH %bb.1 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.1: | |
| ; CHECK-NEXT: successors: %bb.3(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY [[REG_SEQUENCE]].sub0 | |
| ; CHECK-NEXT: S_BRANCH %bb.3 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.2: | |
| ; CHECK-NEXT: successors: %bb.4(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[REG_SEQUENCE]].sub1 | |
| ; CHECK-NEXT: S_BRANCH %bb.4 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.3: | |
| ; CHECK-NEXT: successors: %bb.5(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY [[COPY]] | |
| ; CHECK-NEXT: $vgpr0 = COPY [[COPY2]] | |
| ; CHECK-NEXT: S_BRANCH %bb.5 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.4: | |
| ; CHECK-NEXT: successors: %bb.5(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY [[COPY1]] | |
| ; CHECK-NEXT: $vgpr1 = COPY [[COPY3]] | |
| ; CHECK-NEXT: S_BRANCH %bb.5 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.5: | |
| ; CHECK-NEXT: S_ENDPGM 0 | |
| bb.0: | |
| successors: %bb.1, %bb.2 | |
| %1:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| %0:vreg_64 = REG_SEQUENCE %1, %subreg.sub0, %2, %subreg.sub1 | |
| %5:sreg_32 = S_MOV_B32 0 | |
| S_CMP_EQ_U32 %5, 0, implicit-def $scc | |
| S_CBRANCH_SCC1 %bb.2, implicit $scc | |
| S_BRANCH %bb.1 | |
| bb.1: | |
| successors: %bb.3 | |
| S_BRANCH %bb.3 | |
| bb.2: | |
| successors: %bb.4 | |
| S_BRANCH %bb.4 | |
| bb.3: | |
| successors: %bb.5 | |
| %3:vgpr_32 = PHI %0.sub0, %bb.1 | |
| $vgpr0 = COPY %3 | |
| S_BRANCH %bb.5 | |
| bb.4: | |
| successors: %bb.5 | |
| %4:vgpr_32 = PHI %0.sub1, %bb.2 | |
| $vgpr1 = COPY %4 | |
| S_BRANCH %bb.5 | |
| bb.5: | |
| S_ENDPGM 0 | |
| ... | |
| # PHI elimination splits bb.1 -> bb.3 to isolate the low-lane source copy | |
| # from the high-lane use in bb.2. bb.3 has only one predecessor, so this | |
| # edge is not critical. The inherited high-lane segment must still be | |
| # shrunk out of the split block. | |
| --- | |
| name: phi_subrange_lane_live_out_split_edge | |
| tracksRegLiveness: true | |
| body: | | |
| ; CHECK-LABEL: name: phi_subrange_lane_live_out_split_edge | |
| ; CHECK: bb.0: | |
| ; CHECK-NEXT: successors: %bb.1(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[V_MOV_B32_e32_]], %subreg.sub0, [[V_MOV_B32_e32_1]], %subreg.sub1 | |
| ; CHECK-NEXT: S_BRANCH %bb.1 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.1: | |
| ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.4(0x40000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 0 | |
| ; CHECK-NEXT: S_CMP_EQ_U32 [[S_MOV_B32_]], 0, implicit-def $scc | |
| ; CHECK-NEXT: S_CBRANCH_SCC1 %bb.2, implicit $scc | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.4: | |
| ; CHECK-NEXT: successors: %bb.3(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY [[REG_SEQUENCE]].sub0 | |
| ; CHECK-NEXT: S_BRANCH %bb.3 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.2: | |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[REG_SEQUENCE]].sub1 | |
| ; CHECK-NEXT: $vgpr1 = COPY [[COPY1]] | |
| ; CHECK-NEXT: S_ENDPGM 0 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.3: | |
| ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY [[COPY]] | |
| ; CHECK-NEXT: $vgpr0 = COPY [[COPY2]] | |
| ; CHECK-NEXT: S_ENDPGM 0 | |
| bb.0: | |
| successors: %bb.1 | |
| %1:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| %0:vreg_64 = REG_SEQUENCE %1, %subreg.sub0, %2, %subreg.sub1 | |
| S_BRANCH %bb.1 | |
| bb.1: | |
| successors: %bb.2, %bb.3 | |
| %5:sreg_32 = S_MOV_B32 0 | |
| S_CMP_EQ_U32 %5, 0, implicit-def $scc | |
| S_CBRANCH_SCC1 %bb.2, implicit $scc | |
| S_BRANCH %bb.3 | |
| bb.2: | |
| %8:vgpr_32 = COPY %0.sub1 | |
| $vgpr1 = COPY %8 | |
| S_ENDPGM 0 | |
| bb.3: | |
| %3:vgpr_32 = PHI %0.sub0, %bb.1 | |
| $vgpr0 = COPY %3 | |
| S_ENDPGM 0 | |
| ... | |
| # Only sub1 is live into the other successor, so the main range is live-out and | |
| # the critical edge bb.1 -> bb.3 is split. The split block inherits every lane, | |
| # but the PHI copy placed there reads only sub0. sub1 must be shrunk out of the | |
| # split block rather than trimmed at the sub0 copy. | |
| --- | |
| name: phi_subrange_lane_live_out_critical_edge | |
| tracksRegLiveness: true | |
| body: | | |
| ; CHECK-LABEL: name: phi_subrange_lane_live_out_critical_edge | |
| ; CHECK: bb.0: | |
| ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[V_MOV_B32_e32_]], %subreg.sub0, [[V_MOV_B32_e32_1]], %subreg.sub1 | |
| ; CHECK-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 0 | |
| ; CHECK-NEXT: S_CMP_EQ_U32 [[S_MOV_B32_]], 0, implicit-def $scc | |
| ; CHECK-NEXT: S_CBRANCH_SCC1 %bb.4, implicit $scc | |
| ; CHECK-NEXT: S_BRANCH %bb.1 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.1: | |
| ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.5(0x40000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 0 | |
| ; CHECK-NEXT: S_CMP_EQ_U32 [[S_MOV_B32_1]], 0, implicit-def $scc | |
| ; CHECK-NEXT: S_CBRANCH_SCC1 %bb.2, implicit $scc | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.5: | |
| ; CHECK-NEXT: successors: %bb.3(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY [[REG_SEQUENCE]].sub0 | |
| ; CHECK-NEXT: S_BRANCH %bb.3 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.2: | |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[REG_SEQUENCE]].sub1 | |
| ; CHECK-NEXT: $vgpr1 = COPY [[COPY1]] | |
| ; CHECK-NEXT: S_ENDPGM 0 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.3: | |
| ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY [[COPY]] | |
| ; CHECK-NEXT: $vgpr0 = COPY [[COPY2]] | |
| ; CHECK-NEXT: S_ENDPGM 0 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.4: | |
| ; CHECK-NEXT: successors: %bb.3(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_2:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 3, implicit $exec | |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY [[V_MOV_B32_e32_2]] | |
| ; CHECK-NEXT: S_BRANCH %bb.3 | |
| bb.0: | |
| successors: %bb.1, %bb.4 | |
| %1:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| %0:vreg_64 = REG_SEQUENCE %1, %subreg.sub0, %2, %subreg.sub1 | |
| %9:sreg_32 = S_MOV_B32 0 | |
| S_CMP_EQ_U32 %9, 0, implicit-def $scc | |
| S_CBRANCH_SCC1 %bb.4, implicit $scc | |
| S_BRANCH %bb.1 | |
| bb.1: | |
| successors: %bb.2, %bb.3 | |
| %5:sreg_32 = S_MOV_B32 0 | |
| S_CMP_EQ_U32 %5, 0, implicit-def $scc | |
| S_CBRANCH_SCC1 %bb.2, implicit $scc | |
| S_BRANCH %bb.3 | |
| bb.2: | |
| %8:vgpr_32 = COPY %0.sub1 | |
| $vgpr1 = COPY %8 | |
| S_ENDPGM 0 | |
| bb.3: | |
| %3:vgpr_32 = PHI %0.sub0, %bb.1, %6, %bb.4 | |
| $vgpr0 = COPY %3 | |
| S_ENDPGM 0 | |
| bb.4: | |
| successors: %bb.3 | |
| %6:vgpr_32 = V_MOV_B32_e32 3, implicit $exec | |
| S_BRANCH %bb.3 | |
| ... | |
| # One PHI reads the whole register and another reads only sub1 from the same | |
| # predecessor. The sub1 copy is the last use of the main range, but sub0 must | |
| # end at the earlier full-register copy. | |
| --- | |
| name: phi_subrange_full_and_lane | |
| tracksRegLiveness: true | |
| body: | | |
| ; CHECK-LABEL: name: phi_subrange_full_and_lane | |
| ; CHECK: bb.0: | |
| ; CHECK-NEXT: successors: %bb.1(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| ; CHECK-NEXT: [[V_MOV_B32_e32_1:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_64 = REG_SEQUENCE [[V_MOV_B32_e32_]], %subreg.sub0, [[V_MOV_B32_e32_1]], %subreg.sub1 | |
| ; CHECK-NEXT: S_BRANCH %bb.1 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.1: | |
| ; CHECK-NEXT: successors: %bb.2(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:vreg_64 = COPY [[REG_SEQUENCE]] | |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY [[REG_SEQUENCE]].sub1 | |
| ; CHECK-NEXT: S_BRANCH %bb.2 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.2: | |
| ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vreg_64 = COPY [[COPY]] | |
| ; CHECK-NEXT: $vgpr0_vgpr1 = COPY [[COPY2]] | |
| ; CHECK-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY [[COPY1]] | |
| ; CHECK-NEXT: $vgpr2 = COPY [[COPY3]] | |
| ; CHECK-NEXT: S_ENDPGM 0 | |
| bb.0: | |
| successors: %bb.1 | |
| %1:vgpr_32 = V_MOV_B32_e32 1, implicit $exec | |
| %2:vgpr_32 = V_MOV_B32_e32 2, implicit $exec | |
| %0:vreg_64 = REG_SEQUENCE %1, %subreg.sub0, %2, %subreg.sub1 | |
| S_BRANCH %bb.1 | |
| bb.1: | |
| successors: %bb.2 | |
| S_BRANCH %bb.2 | |
| bb.2: | |
| %3:vreg_64 = PHI %0, %bb.1 | |
| %4:vgpr_32 = PHI %0.sub1, %bb.1 | |
| $vgpr0_vgpr1 = COPY %3 | |
| $vgpr2 = COPY %4 | |
| S_ENDPGM 0 | |
| ... |