| # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py |
| # RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx906 -verify-coalescing -verify-machineinstrs -amdgpu-enable-rewrite-partial-reg-uses=false -start-before=register-coalescer -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 [[COPY:%[0-9]+]].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 [[COPY:%[0-9]+]].sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 [[COPY]].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 [[COPY:%[0-9]+]].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 [[COPY]].sub0 |
| ; CHECK-NEXT: S_NOP 0, implicit undef [[COPY]].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 [[COPY:%[0-9]+]].sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 [[COPY]].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 [[COPY:%[0-9]+]].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 [[COPY:%[0-9]+]].sub1:vreg_64 = nofpexcept V_MUL_F32_e32 0, [[COPY]].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 [[COPY:%[0-9]+]].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: [[COPY:%[0-9]+]].sub1:vreg_64 = nofpexcept V_MUL_F32_e32 0, [[COPY]].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 [[COPY:%[0-9]+]].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 [[COPY]].sub0 |
| ; CHECK-NEXT: undef [[COPY:%[0-9]+]].sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 [[COPY]].sub1, implicit $mode, implicit $exec |
| ; CHECK-NEXT: S_BRANCH %bb.1 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.3: |
| ; CHECK-NEXT: S_NOP 0, implicit undef [[COPY]].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 [[COPY:%[0-9]+]].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 [[COPY]].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 [[COPY:%[0-9]+]].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 [[COPY]].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: dead undef [[COPY:%[0-9]+]].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: dead undef [[COPY:%[0-9]+]].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: dead undef [[COPY:%[0-9]+]].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 [[COPY:%[0-9]+]].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 [[COPY:%[0-9]+]].sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 [[COPY]].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 [[COPY:%[0-9]+]].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: [[COPY:%[0-9]+]].sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 [[COPY]].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 |
| |
| ... |