diff options
| -rw-r--r-- | llvm/lib/CodeGen/ScheduleDAGInstrs.cpp | 11 | ||||
| -rw-r--r-- | llvm/test/CodeGen/AMDGPU/post-ra-sched-kill-bundle-use-inst.mir | 42 |
2 files changed, 47 insertions, 6 deletions
diff --git a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp index 40ed1b90b7d..a5380108896 100644 --- a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -1104,22 +1104,21 @@ void ScheduleDAGInstrs::fixupKills(MachineBasicBlock &MBB) { if (!MI.isBundled()) { toggleKills(MRI, LiveRegs, MI, true); } else { - MachineBasicBlock::instr_iterator First = MI.getIterator(); - if (MI.isBundle()) { + MachineBasicBlock::instr_iterator Bundle = MI.getIterator(); + if (MI.isBundle()) toggleKills(MRI, LiveRegs, MI, false); - ++First; - } + // Some targets make the (questionable) assumtion that the instructions // inside the bundle are ordered and consequently only the last use of // a register inside the bundle can kill it. - MachineBasicBlock::instr_iterator I = std::next(First); + MachineBasicBlock::instr_iterator I = std::next(Bundle); while (I->isBundledWithSucc()) ++I; do { if (!I->isDebugInstr()) toggleKills(MRI, LiveRegs, *I, true); --I; - } while(I != First); + } while (I != Bundle); } } } diff --git a/llvm/test/CodeGen/AMDGPU/post-ra-sched-kill-bundle-use-inst.mir b/llvm/test/CodeGen/AMDGPU/post-ra-sched-kill-bundle-use-inst.mir new file mode 100644 index 00000000000..be0dbe09ae2 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/post-ra-sched-kill-bundle-use-inst.mir @@ -0,0 +1,42 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=amdgcn-mesa-mesa3d -mcpu=gfx900 -run-pass=post-RA-sched -verify-machineinstrs -o - %s | FileCheck %s + +# The scheduler was not inspecting the first instruction in the bundle +# when adding kill flags, so it would incorrectly mark the first use +# of $vgpr0 as killed. + +--- +name: kill_flag_use_first_bundle_inst +tracksRegLiveness: true +machineFunctionInfo: + isEntryFunction: true +body: | + bb.0: + liveins: $sgpr4_sgpr5, $sgpr7 + + ; CHECK-LABEL: name: kill_flag_use_first_bundle_inst + ; CHECK: liveins: $sgpr4_sgpr5, $sgpr7 + ; CHECK: renamable $sgpr0 = S_LOAD_DWORD_IMM killed renamable $sgpr4_sgpr5, 0, 0, 0 + ; CHECK: $m0 = S_MOV_B32 -1 + ; CHECK: $vgpr0 = V_MOV_B32_e32 killed $sgpr0, implicit $exec, implicit $exec + ; CHECK: BUNDLE implicit $vgpr0, implicit $m0, implicit $exec { + ; CHECK: DS_GWS_INIT $vgpr0, 8, -1, implicit $m0, implicit $exec + ; CHECK: S_WAITCNT 0 + ; CHECK: } + ; CHECK: BUNDLE implicit killed $vgpr0, implicit $m0, implicit $exec { + ; CHECK: DS_GWS_BARRIER killed $vgpr0, 8, -1, implicit $m0, implicit $exec + ; CHECK: S_WAITCNT 0 + ; CHECK: } + renamable $sgpr0 = S_LOAD_DWORD_IMM killed renamable $sgpr4_sgpr5, 0, 0, 0 + $m0 = S_MOV_B32 -1 + $vgpr0 = V_MOV_B32_e32 $sgpr0, implicit $exec, implicit $exec + BUNDLE implicit $vgpr0, implicit $m0, implicit $exec { + DS_GWS_INIT $vgpr0, 8, -1, implicit $m0, implicit $exec + S_WAITCNT 0 + } + BUNDLE implicit killed $vgpr0, implicit $m0, implicit $exec { + DS_GWS_BARRIER $vgpr0, 8, -1, implicit $m0, implicit $exec + S_WAITCNT 0 + } + +... |

