OSDN Git Service

LiveIntervalAnalysis: Fix missing case in pruneSubRegValues()
authorMatthias Braun <matze@braunis.de>
Fri, 19 May 2017 00:18:03 +0000 (00:18 +0000)
committerMatthias Braun <matze@braunis.de>
Fri, 19 May 2017 00:18:03 +0000 (00:18 +0000)
pruneSubRegValues() needs to remove subregister ranges starting at
instructions that later get removed by eraseInstrs(). It missed to check
one case in which eraseInstrs() would remove an instruction.

Fixes http://llvm.org/PR32688

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

lib/CodeGen/RegisterCoalescer.cpp
test/CodeGen/AMDGPU/regcoalesce-prune.mir [new file with mode: 0644]

index 1803ea2..7b3a5d5 100644 (file)
@@ -2666,11 +2666,17 @@ void JoinVals::pruneSubRegValues(LiveInterval &LI, LaneBitmask &ShrinkMask) {
   // Look for values being erased.
   bool DidPrune = false;
   for (unsigned i = 0, e = LR.getNumValNums(); i != e; ++i) {
-    if (Vals[i].Resolution != CR_Erase)
+    // We should trigger in all cases in which eraseInstrs() does something.
+    // match what eraseInstrs() is doing, print a message so
+    if (Vals[i].Resolution != CR_Erase &&
+        (Vals[i].Resolution != CR_Keep || !Vals[i].ErasableImplicitDef ||
+         !Vals[i].Pruned))
       continue;
 
     // Check subranges at the point where the copy will be removed.
     SlotIndex Def = LR.getValNumInfo(i)->def;
+    // Print message so mismatches with eraseInstrs() can be diagnosed.
+    DEBUG(dbgs() << "\t\tExpecting instruction removal at " << Def << '\n');
     for (LiveInterval::SubRange &S : LI.subranges()) {
       LiveQueryResult Q = S.Query(Def);
 
diff --git a/test/CodeGen/AMDGPU/regcoalesce-prune.mir b/test/CodeGen/AMDGPU/regcoalesce-prune.mir
new file mode 100644 (file)
index 0000000..7d8c7bb
--- /dev/null
@@ -0,0 +1,31 @@
+# RUN: llc -o - %s -mtriple=amdgcn-amd-amdhsa-opencl -run-pass=simple-register-coalescing | FileCheck %s
+---
+# Checks for a bug where subregister liveranges were not properly pruned for
+# an IMPLCITI_DEF that gets removed completely.
+#
+# CHECK-LABEL: name: func
+# IMPLICIT_DEF should be gone without llc hitting assertion failures.
+# CHECK-NOT: IMPLCITI_DEF
+name: func
+tracksRegLiveness: true
+body: |
+  bb.0:
+    undef %5.sub1 = V_MOV_B32_e32 0, implicit %exec
+    %6 = COPY %5
+    S_CBRANCH_VCCZ %bb.2, implicit undef %vcc
+
+  bb.1:
+    %1 : sreg_32_xm0 = S_MOV_B32 0
+    undef %0.sub0 : sreg_64 = COPY %1
+    %0.sub1 = COPY %1
+    %4 : vreg_64 = COPY killed %0
+    %5 : vreg_64 = IMPLICIT_DEF
+    %6 : vreg_64 = COPY killed %4
+
+  bb.2:
+    %2 : vgpr_32 = V_CVT_F32_I32_e32 killed %5.sub1, implicit %exec
+
+  bb.3:
+    %3 : vgpr_32 = V_CVT_F32_I32_e32 killed %6.sub1, implicit %exec
+    S_ENDPGM
+...