]> granicus.if.org Git - llvm/commitdiff
ScheduleDAG: Fix incorrectly killing registers in bundles
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Fri, 5 Jul 2019 15:32:28 +0000 (15:32 +0000)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Fri, 5 Jul 2019 15:32:28 +0000 (15:32 +0000)
When looking for uses/defs to add kill flags, the iterator was double
incremented, skipping the first instruction in the bundle. The use
register in the first bundle instruction was then incorrectly killed.
The "First" instruction should be the BUNDLE itself as the proper
reverse iterator endpoint.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365216 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/ScheduleDAGInstrs.cpp
test/CodeGen/AMDGPU/post-ra-sched-kill-bundle-use-inst.mir [new file with mode: 0644]

index 40ed1b90b7ddb99d878694a5f06e93fb5d110e48..a538010889607c716d54d2e7fe28c8c0be2d8ba0 100644 (file)
@@ -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/test/CodeGen/AMDGPU/post-ra-sched-kill-bundle-use-inst.mir b/test/CodeGen/AMDGPU/post-ra-sched-kill-bundle-use-inst.mir
new file mode 100644 (file)
index 0000000..be0dbe0
--- /dev/null
@@ -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
+    }
+
+...