# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py # RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx906 -verify-coalescing -verify-machineinstrs -start-before=simple-register-coalescing -stop-after=machine-scheduler -o - %s | FileCheck %s # Tests that break due to the handling of partially undef registers # when whole register identity copies are erased. # Make sure there is no verifier error after # RenameIndepependentSubregs processes this. The coalescer would # remove the identity copy in %bb.1, and leave behind a dummy interval # across bb.1 with no corresponding value anywhere in the function. --- name: identity_copy_undef_subrange tracksRegLiveness: true body: | ; CHECK-LABEL: name: identity_copy_undef_subrange ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: liveins: $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = COPY $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_CBRANCH_EXECNZ %bb.1, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 %0.sub1, implicit $mode, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.1 bb.0: liveins: $vgpr0 undef %0.sub1:vreg_64 = COPY killed $vgpr0 bb.1: successors: %bb.2, %bb.1 %0:vreg_64 = COPY %0 S_CBRANCH_EXECNZ %bb.1, implicit $exec S_BRANCH %bb.2 bb.2: undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 killed %0.sub1, implicit $mode, implicit $exec S_BRANCH %bb.1 ... # Test another use of the register inside the block. --- name: identity_copy_undef_subrange_other_uses0 tracksRegLiveness: true body: | ; CHECK-LABEL: name: identity_copy_undef_subrange_other_uses0 ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: liveins: $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = COPY $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_NOP 0, implicit undef %0.sub0 ; CHECK-NEXT: S_NOP 0, implicit undef %0.sub0 ; CHECK-NEXT: S_CBRANCH_EXECNZ %bb.1, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 %0.sub1, implicit $mode, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.1 bb.0: liveins: $vgpr0 undef %0.sub1:vreg_64 = COPY killed $vgpr0 bb.1: successors: %bb.2, %bb.1 %0:vreg_64 = COPY %0 S_NOP 0, implicit %0.sub0 S_NOP 0, implicit %0.sub0 S_CBRANCH_EXECNZ %bb.1, implicit $exec S_BRANCH %bb.2 bb.2: undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 killed %0.sub1, implicit $mode, implicit $exec S_BRANCH %bb.1 ... --- name: second_identity_copy tracksRegLiveness: true body: | ; CHECK-LABEL: name: second_identity_copy ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: liveins: $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = COPY $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_CBRANCH_EXECNZ %bb.1, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = nofpexcept V_MUL_F32_e32 0, %0.sub1, implicit $mode, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.1 bb.0: liveins: $vgpr0 undef %0.sub1:vreg_64 = COPY killed $vgpr0 bb.1: successors: %bb.2, %bb.1 %0:vreg_64 = COPY killed %0 %0:vreg_64 = COPY %0 S_CBRANCH_EXECNZ %bb.1, implicit $exec S_BRANCH %bb.2 bb.2: undef %0.sub1:vreg_64 = nofpexcept V_MUL_F32_e32 0, killed %0.sub1, implicit $mode, implicit $exec S_BRANCH %bb.1 ... --- name: second_identity_copy_undef_lane_outblock tracksRegLiveness: true body: | ; CHECK-LABEL: name: second_identity_copy_undef_lane_outblock ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: liveins: $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = COPY $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_CBRANCH_EXECNZ %bb.1, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %0.sub1:vreg_64 = nofpexcept V_MUL_F32_e32 0, %0.sub1, implicit $mode, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.1 bb.0: liveins: $vgpr0 undef %0.sub1:vreg_64 = COPY killed $vgpr0 bb.1: successors: %bb.2, %bb.1 %0:vreg_64 = COPY killed %0 %0:vreg_64 = COPY %0 S_CBRANCH_EXECNZ %bb.1, implicit $exec S_BRANCH %bb.2 bb.2: %0.sub1:vreg_64 = nofpexcept V_MUL_F32_e32 0, killed %0.sub1, implicit $mode, implicit $exec S_BRANCH %bb.1 ... # The same value number appears in multiple blocks --- name: identity_copy_undef_subrange_null_vninfo_to_remove tracksRegLiveness: true body: | ; CHECK-LABEL: name: identity_copy_undef_subrange_null_vninfo_to_remove ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: liveins: $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = COPY $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.3(0x40000000), %bb.2(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_CBRANCH_EXECNZ %bb.3, implicit $exec ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_NOP 0, implicit undef %0.sub0 ; CHECK-NEXT: undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 %0.sub1, implicit $mode, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.1 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.3: ; CHECK-NEXT: S_NOP 0, implicit undef %0.sub0 bb.0: liveins: $vgpr0 undef %0.sub1:vreg_64 = COPY killed $vgpr0 bb.1: %0:vreg_64 = COPY %0 S_CBRANCH_EXECNZ %bb.3, implicit $exec bb.2: S_NOP 0, implicit %0.sub0 undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 killed %0.sub1, implicit $mode, implicit $exec S_BRANCH %bb.1 bb.3: S_NOP 0, implicit %0.sub0 ... --- name: undef_copy_self_loop0 tracksRegLiveness: true body: | ; CHECK-LABEL: name: undef_copy_self_loop0 ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: liveins: $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = COPY $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_CBRANCH_EXECNZ %bb.1, implicit $exec ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: S_NOP 0, implicit undef %0.sub0 bb.0: liveins: $vgpr0 undef %0.sub1:vreg_64 = COPY killed $vgpr0 bb.1: %0:vreg_64 = COPY %0 S_CBRANCH_EXECNZ %bb.1, implicit $exec bb.2: S_NOP 0, implicit %0.sub0 ... --- name: undef_copy_self_loop1 tracksRegLiveness: true body: | ; CHECK-LABEL: name: undef_copy_self_loop1 ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: liveins: $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = COPY $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_CBRANCH_EXECNZ %bb.1, implicit $exec ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: S_NOP 0, implicit %0.sub1 bb.0: liveins: $vgpr0 undef %0.sub1:vreg_64 = COPY killed $vgpr0 bb.1: %0:vreg_64 = COPY %0 S_CBRANCH_EXECNZ %bb.1, implicit $exec bb.2: S_NOP 0, implicit %0.sub1 ... # The coalescing of the %0 = %2 COPY in %bb.2 needs to prune the dead # phi range across %bb.1 after it is erased. --- name: prune_subrange_phi_value_0 tracksRegLiveness: true body: | ; CHECK-LABEL: name: prune_subrange_phi_value_0 ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: liveins: $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %2.sub1:vreg_64 = COPY $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_CBRANCH_EXECNZ %bb.1, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_BRANCH %bb.1 bb.0: liveins: $vgpr0 undef %0.sub1:vreg_64 = COPY killed $vgpr0 bb.1: successors: %bb.2, %bb.1 %1:vreg_64 = COPY killed %0 %0:vreg_64 = COPY %1 S_CBRANCH_EXECNZ %bb.1, implicit $exec S_BRANCH %bb.2 bb.2: undef %2.sub1:vreg_64 = COPY %0.sub1 %0:vreg_64 = COPY killed %2 S_BRANCH %bb.1 ... --- name: prune_subrange_phi_value_0_0 tracksRegLiveness: true body: | ; CHECK-LABEL: name: prune_subrange_phi_value_0_0 ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: liveins: $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = COPY $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_CBRANCH_EXECNZ %bb.1, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_BRANCH %bb.1 bb.0: liveins: $vgpr0 undef %0.sub1:vreg_64 = COPY killed $vgpr0 bb.1: successors: %bb.2, %bb.1 %1:vreg_64 = COPY killed %0 %0:vreg_64 = COPY %1 S_CBRANCH_EXECNZ %bb.1, implicit $exec S_BRANCH %bb.2 bb.2: undef %0.sub1:vreg_64 = COPY %0.sub1 S_BRANCH %bb.1 ... --- name: prune_subrange_phi_value_0_1 tracksRegLiveness: true body: | ; CHECK-LABEL: name: prune_subrange_phi_value_0_1 ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: liveins: $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = COPY $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_CBRANCH_EXECNZ %bb.1, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_BRANCH %bb.1 bb.0: liveins: $vgpr0 undef %0.sub1:vreg_64 = COPY killed $vgpr0 bb.1: successors: %bb.2, %bb.1 %1:vreg_64 = COPY killed %0 %0:vreg_64 = COPY %1 S_CBRANCH_EXECNZ %bb.1, implicit $exec S_BRANCH %bb.2 bb.2: S_BRANCH %bb.1 ... # Variant of testcase that asserts since there wasn't already an # incoming segment at the erased copy, and no valid end point. --- name: prune_subrange_phi_value_1 tracksRegLiveness: true body: | ; CHECK-LABEL: name: prune_subrange_phi_value_1 ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: liveins: $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = COPY $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_CBRANCH_EXECNZ %bb.1, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 %0.sub1, implicit $mode, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.1 bb.0: liveins: $vgpr0 undef %0.sub1:vreg_64 = COPY killed $vgpr0 bb.1: successors: %bb.2, %bb.1 %0:vreg_64 = COPY killed %0 S_CBRANCH_EXECNZ %bb.1, implicit $exec S_BRANCH %bb.2 bb.2: undef %1.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 killed %0.sub1, implicit $mode, implicit $exec %0:vreg_64 = COPY killed %1 S_BRANCH %bb.1 ... --- name: prune_subrange_phi_value_2 tracksRegLiveness: true body: | ; CHECK-LABEL: name: prune_subrange_phi_value_2 ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: liveins: $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: undef %0.sub1:vreg_64 = COPY $vgpr0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: S_CBRANCH_EXECNZ %bb.1, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 %0.sub1, implicit $mode, implicit $exec ; CHECK-NEXT: S_BRANCH %bb.1 bb.0: liveins: $vgpr0 undef %0.sub1:vreg_64 = COPY killed $vgpr0 bb.1: successors: %bb.2, %bb.1 %0:vreg_64 = COPY killed %0 S_CBRANCH_EXECNZ %bb.1, implicit $exec S_BRANCH %bb.2 bb.2: %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 %0.sub1, implicit $mode, implicit $exec S_BRANCH %bb.1 ...