| # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6 |
| # RUN: llc -mtriple=amdgcn -mcpu=gfx908 -run-pass=si-fold-operands -o - %s | FileCheck %s |
| |
| # When SIFoldOperands folds a COPY source into a use inside a BUNDLE, it |
| # must also update the BUNDLE header's matching implicit operand. |
| # Without it, for example after folding %5.sub1 into the bundle |
| # |
| # %8:vgpr_32 = COPY killed %5.sub1:vreg_128 |
| # BUNDLE implicit killed %8:vgpr_32, ... { |
| # DS_GWS_INIT %5.sub1:vreg_128, ... |
| # } |
| # |
| # the header still uses %8, so the COPY can't be deleted. Its `killed %5.sub1` |
| # is now stale and MachineVerifier reports "Using a killed virtual register". |
| # Updating the header's implicit operand from %8 to %5.sub1 lets the dead-COPY |
| # cleanup remove the COPY and its stale kill flag. |
| |
| |
| --- |
| name: fold_into_bundled_use |
| tracksRegLiveness: true |
| body: | |
| bb.0: |
| liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 |
| |
| ; CHECK-LABEL: name: fold_into_bundled_use |
| ; CHECK: liveins: $vgpr0, $vgpr1, $vgpr2, $vgpr3 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr0 |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr_32 = COPY $vgpr1 |
| ; CHECK-NEXT: [[COPY2:%[0-9]+]]:vgpr_32 = COPY $vgpr2 |
| ; CHECK-NEXT: [[COPY3:%[0-9]+]]:vgpr_32 = COPY $vgpr3 |
| ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:vreg_128 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1, [[COPY2]], %subreg.sub2, [[COPY3]], %subreg.sub3 |
| ; CHECK-NEXT: $m0 = S_MOV_B32 0 |
| ; CHECK-NEXT: BUNDLE implicit [[REG_SEQUENCE]].sub0, implicit $m0, implicit $exec :: (store (s32) into custom "GWSResource") { |
| ; CHECK-NEXT: DS_GWS_INIT [[REG_SEQUENCE]].sub0, 0, implicit $m0, implicit $exec :: (store (s32) into custom "GWSResource") |
| ; CHECK-NEXT: S_WAITCNT .Vmcnt_0_Expcnt_0_Lgkmcnt_0 |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: BUNDLE implicit [[REG_SEQUENCE]].sub1, implicit $m0, implicit $exec :: (store (s32) into custom "GWSResource") { |
| ; CHECK-NEXT: DS_GWS_INIT [[REG_SEQUENCE]].sub1, 0, implicit $m0, implicit $exec :: (store (s32) into custom "GWSResource") |
| ; CHECK-NEXT: S_WAITCNT .Vmcnt_0_Expcnt_0_Lgkmcnt_0 |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: S_ENDPGM 0 |
| %0:vgpr_32 = COPY $vgpr0 |
| %1:vgpr_32 = COPY $vgpr1 |
| %2:vgpr_32 = COPY $vgpr2 |
| %3:vgpr_32 = COPY $vgpr3 |
| %4:vreg_128 = REG_SEQUENCE %0:vgpr_32, %subreg.sub0, %1:vgpr_32, %subreg.sub1, %2:vgpr_32, %subreg.sub2, %3:vgpr_32, %subreg.sub3 |
| %5:vgpr_32 = COPY %4.sub0:vreg_128 |
| %6:vgpr_32 = COPY %4.sub1:vreg_128 |
| $m0 = S_MOV_B32 0 |
| BUNDLE implicit %5:vgpr_32, implicit $m0, implicit $exec :: (store (s32) into custom "GWSResource") { |
| DS_GWS_INIT %5:vgpr_32, 0, implicit $m0, implicit $exec :: (store (s32) into custom "GWSResource") |
| S_WAITCNT 0 |
| } |
| BUNDLE implicit %6:vgpr_32, implicit $m0, implicit $exec :: (store (s32) into custom "GWSResource") { |
| DS_GWS_INIT %6:vgpr_32, 0, implicit $m0, implicit $exec :: (store (s32) into custom "GWSResource") |
| S_WAITCNT 0 |
| } |
| S_ENDPGM 0 |
| ... |