# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2 # RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1031 -run-pass=register-coalescer -verify-coalescing -o - %s | FileCheck %s # Make sure coalescing doesn't produce "no live segment at def" when # there is a live out implicit_def with subranges. # %1 will be coalesced into %0. %0 is a cross block implicit_def that # cannot be deleted. The def of %0 in %bb.2 is a live out subregister # def of the same register. We need to ensure that the resulting # subrange for %0.sub0 includes the def in %bb.1 --- name: liveout_implicit_def_super_reg_redefine_sub0_implicit_def tracksRegLiveness: true body: | ; CHECK-LABEL: name: liveout_implicit_def_super_reg_redefine_sub0_implicit_def ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_CBRANCH_SCC0 %bb.2, implicit undef $scc ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.3(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub0:sgpr_128 = S_MOV_B32 0 ; CHECK-NEXT: S_BRANCH %bb.3 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: successors: %bb.3(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub0:sgpr_128 = IMPLICIT_DEF ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.3: ; CHECK-NEXT: S_NOP 0, implicit %0 ; CHECK-NEXT: S_NOP 0, implicit %0.sub0 ; CHECK-NEXT: S_ENDPGM 0 bb.0: S_CBRANCH_SCC0 %bb.2, implicit undef $scc bb.1: %0:sgpr_128 = IMPLICIT_DEF %1:sgpr_32 = S_MOV_B32 0 S_BRANCH %bb.3 bb.2: undef %0.sub0:sgpr_128 = IMPLICIT_DEF %1:sgpr_32 = COPY %0.sub0 bb.3: S_NOP 0, implicit %0 S_NOP 0, implicit %1 S_ENDPGM 0 ... # Redef of sub0 is a meaningful value. --- name: liveout_implicit_def_redefine_sub0_undef_other tracksRegLiveness: true body: | ; CHECK-LABEL: name: liveout_implicit_def_redefine_sub0_undef_other ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_CBRANCH_SCC0 %bb.2, implicit undef $scc ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.3(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub0:sgpr_128 = S_MOV_B32 0 ; CHECK-NEXT: S_BRANCH %bb.3 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: successors: %bb.3(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub0:sgpr_128 = S_MOV_B32 9 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.3: ; CHECK-NEXT: S_NOP 0, implicit %0 ; CHECK-NEXT: S_NOP 0, implicit %0.sub0 ; CHECK-NEXT: S_ENDPGM 0 bb.0: S_CBRANCH_SCC0 %bb.2, implicit undef $scc bb.1: %0:sgpr_128 = IMPLICIT_DEF %1:sgpr_32 = S_MOV_B32 0 S_BRANCH %bb.3 bb.2: undef %0.sub0:sgpr_128 = S_MOV_B32 9 %1:sgpr_32 = COPY %0.sub0 bb.3: S_NOP 0, implicit %0 S_NOP 0, implicit %1 S_ENDPGM 0 ... # The initial def of the register doesn't doesn't cover the redefined # lanes. This had no error but was useful to compare against the # failing cases. --- name: only_redefine_undefined_lanes tracksRegLiveness: true body: | ; CHECK-LABEL: name: only_redefine_undefined_lanes ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_CBRANCH_SCC0 %bb.2, implicit undef $scc ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.3(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_NOP 0, implicit-def undef %0.sub1_sub2_sub3 ; CHECK-NEXT: %0.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.3 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: successors: %bb.3(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub0:vreg_128 = V_MOV_B32_e32 9, implicit $exec ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.3: ; CHECK-NEXT: S_NOP 0, implicit %0 ; CHECK-NEXT: S_NOP 0, implicit %0.sub0 ; CHECK-NEXT: S_ENDPGM 0 bb.0: S_CBRANCH_SCC0 %bb.2, implicit undef $scc bb.1: S_NOP 0, implicit-def undef %0.sub1_sub2_sub3:vreg_128 %1:vgpr_32 = V_MOV_B32_e32 0, implicit $exec S_BRANCH %bb.3 bb.2: undef %0.sub0:vreg_128 = V_MOV_B32_e32 9, implicit $exec %1:vgpr_32 = COPY %0.sub0 bb.3: S_NOP 0, implicit %0 S_NOP 0, implicit %1 S_ENDPGM 0 ...