[llvm] [RegisterCoalescer] Deferring deletion of instructions in `ErasedInstrs` until the end of an iteration (PR #79820)

Quentin Dian via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 8 22:41:58 PST 2024


https://github.com/DianQK updated https://github.com/llvm/llvm-project/pull/79820

>From 646c95f6169fa556a725ed9e3bb93be557499cbb Mon Sep 17 00:00:00 2001
From: DianQK <dianqk at dianqk.net>
Date: Thu, 8 Feb 2024 20:40:02 +0800
Subject: [PATCH 1/5] Pre-commit test cases

---
 .../register-coalescer-crash-pr79718.mir      | 128 ++++++++++++++++++
 1 file changed, 128 insertions(+)
 create mode 100644 llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir

diff --git a/llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir b/llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir
new file mode 100644
index 0000000000000..dab679c6250b7
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir
@@ -0,0 +1,128 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
+# RUN: llc -o - %s -mtriple=loongarch64 \
+# RUN:  -run-pass=register-coalescer -join-liveintervals=1 -join-splitedges=0 2>&1 | FileCheck %s
+
+---
+name:            foo
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $r4, $r5, $r6, $r7, $r8
+
+    %22:gpr = COPY killed $r8
+    %21:gpr = COPY killed $r7
+    %20:gpr = COPY killed $r6
+    %19:gpr = COPY killed $r5
+    %18:gpr = COPY killed $r4
+    %29:gpr = COPY $r0
+    %27:gpr = COPY killed %29
+    %30:gpr = ANDI killed %19, 1
+    %41:gpr = ORI $r0, 1
+    %35:gpr = ANDI killed %20, 1
+    %36:gpr = ANDI killed %21, 1
+    %39:gpr = ANDI killed %22, 1
+    %43:gpr = COPY %27
+    %44:gpr = COPY killed %27
+    %45:gpr = IMPLICIT_DEF
+
+  bb.1:
+    %2:gpr = COPY killed %45
+    %1:gpr = COPY killed %44
+    %0:gpr = COPY killed %43
+    %46:gpr = COPY %0
+    %47:gpr = COPY %1
+    %48:gpr = COPY killed %1
+    %49:gpr = COPY killed %2
+
+  bb.2:
+    successors: %bb.3, %bb.4
+
+    %6:gpr = COPY killed %49
+    %5:gpr = COPY killed %48
+    %4:gpr = COPY killed %47
+    %3:gpr = COPY killed %46
+    BEQZ %30, %bb.4
+
+  bb.3:
+    %51:gpr = COPY killed %4
+    %52:gpr = COPY killed %5
+    PseudoBR %bb.9
+
+  bb.4:
+    %50:gpr = COPY killed %5
+
+  bb.5:
+    successors: %bb.7(0x7c000000), %bb.6(0x04000000)
+
+    %7:gpr = COPY killed %50
+    dead %33:gpr = LD_D $r0, 8
+    dead %34:gpr = LD_D $r0, 0
+    BNEZ %35, %bb.7
+
+  bb.6:
+    %32:gpr = COPY $r0
+    %31:gpr = COPY killed %32
+    %53:gpr = COPY killed %31
+    %54:gpr = COPY killed %6
+    PseudoBR %bb.11
+
+  bb.7:
+    successors: %bb.8(0x7c000000), %bb.10(0x04000000)
+
+    BEQZ %36, %bb.10
+    PseudoBR %bb.8
+
+  bb.8:
+    successors: %bb.9(0x04000000), %bb.5(0x7c000000)
+
+    %8:gpr = ADDI_D killed %7, 1
+    %50:gpr = COPY %8
+    %51:gpr = COPY %8
+    %52:gpr = COPY killed %8
+    BEQZ %39, %bb.5
+    PseudoBR %bb.9
+
+  bb.9:
+    %10:gpr = COPY killed %52
+    %9:gpr = COPY killed %51
+    %40:gpr = COPY $r0
+    ST_B killed %40, %18, 0
+    %55:gpr = COPY killed %3
+    %56:gpr = COPY killed %9
+    %57:gpr = COPY killed %10
+    %58:gpr = COPY killed %6
+    PseudoBR %bb.12
+
+  bb.10:
+    %42:gpr = ADDI_D killed %7, 1
+    %53:gpr = COPY %41
+    %54:gpr = COPY killed %42
+
+  bb.11:
+    %13:gpr = COPY killed %54
+    %12:gpr = COPY killed %53
+    %38:gpr = COPY $r0
+    ST_D killed %38, %18, 0
+    %55:gpr = COPY %13
+    %56:gpr = COPY %12
+    %57:gpr = COPY killed %12
+    %58:gpr = COPY killed %13
+
+  bb.12:
+    successors: %bb.2(0x7c000000), %bb.1(0x04000000)
+
+    %17:gpr = COPY killed %58
+    %16:gpr = COPY killed %57
+    %15:gpr = COPY killed %56
+    %14:gpr = COPY killed %55
+    %43:gpr = COPY %14
+    %44:gpr = COPY %15
+    %45:gpr = COPY %17
+    %46:gpr = COPY killed %14
+    %47:gpr = COPY killed %15
+    %48:gpr = COPY killed %16
+    %49:gpr = COPY killed %17
+    BEQ %0, %41, %bb.2
+    PseudoBR %bb.1
+
+...

>From 00254d3d7ab40863106af64ee5ba825424e3271d Mon Sep 17 00:00:00 2001
From: DianQK <dianqk at dianqk.net>
Date: Thu, 8 Feb 2024 20:42:12 +0800
Subject: [PATCH 2/5] [RegisterCoalescer] Deferring deletion of instructions in
 ErasedInstrs until the end of an iteration

---
 llvm/lib/CodeGen/RegisterCoalescer.cpp        | 16 ++--
 .../register-coalescer-crash-pr79718.mir      | 87 ++++++++++++++++++-
 2 files changed, 97 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index cbb1a74049fbd..d3125fba67206 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -236,7 +236,8 @@ namespace {
     /// was successfully coalesced away. If it is not currently possible to
     /// coalesce this interval, but it may be possible if other things get
     /// coalesced, then it returns true by reference in 'Again'.
-    bool joinCopy(MachineInstr *CopyMI, bool &Again);
+    bool joinCopy(MachineInstr *CopyMI, bool &Again,
+                  SmallPtrSetImpl<MachineInstr *> &CurrentErasedInstrs);
 
     /// Attempt to join these two intervals.  On failure, this
     /// returns false.  The output "SrcInt" will not have been modified, so we
@@ -1964,7 +1965,9 @@ void RegisterCoalescer::setUndefOnPrunedSubRegUses(LiveInterval &LI,
   LIS->shrinkToUses(&LI);
 }
 
-bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
+bool RegisterCoalescer::joinCopy(
+    MachineInstr *CopyMI, bool &Again,
+    SmallPtrSetImpl<MachineInstr *> &CurrentErasedInstrs) {
   Again = false;
   LLVM_DEBUG(dbgs() << LIS->getInstructionIndex(*CopyMI) << '\t' << *CopyMI);
 
@@ -2156,7 +2159,9 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
   // CopyMI has been erased by joinIntervals at this point. Remove it from
   // ErasedInstrs since copyCoalesceWorkList() won't add a successful join back
   // to the work list. This keeps ErasedInstrs from growing needlessly.
-  ErasedInstrs.erase(CopyMI);
+  if (ErasedInstrs.erase(CopyMI))
+    // But we may encounter the instruction again in this iteration.
+    CurrentErasedInstrs.insert(CopyMI);
 
   // Rewrite all SrcReg operands to DstReg.
   // Also update DstReg operands to include DstIdx if it is set.
@@ -3982,17 +3987,18 @@ void RegisterCoalescer::lateLiveIntervalUpdate() {
 bool RegisterCoalescer::
 copyCoalesceWorkList(MutableArrayRef<MachineInstr*> CurrList) {
   bool Progress = false;
+  SmallPtrSet<MachineInstr *, 4> CurrentErasedInstrs;
   for (MachineInstr *&MI : CurrList) {
     if (!MI)
       continue;
     // Skip instruction pointers that have already been erased, for example by
     // dead code elimination.
-    if (ErasedInstrs.count(MI)) {
+    if (ErasedInstrs.count(MI) || CurrentErasedInstrs.count(MI)) {
       MI = nullptr;
       continue;
     }
     bool Again = false;
-    bool Success = joinCopy(MI, Again);
+    bool Success = joinCopy(MI, Again, CurrentErasedInstrs);
     Progress |= Success;
     if (Success || !Again)
       MI = nullptr;
diff --git a/llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir b/llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir
index dab679c6250b7..bfa8aba55dbc9 100644
--- a/llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir
+++ b/llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir
@@ -1,11 +1,96 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
 # RUN: llc -o - %s -mtriple=loongarch64 \
-# RUN:  -run-pass=register-coalescer -join-liveintervals=1 -join-splitedges=0 2>&1 | FileCheck %s
+# RUN:  -run-pass=register-coalescer -join-liveintervals=1 -join-splitedges=0 | FileCheck %s
 
 ---
 name:            foo
 tracksRegLiveness: true
 body:             |
+  ; CHECK-LABEL: name: foo
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
+  ; CHECK-NEXT:   liveins: $r4, $r5, $r6, $r7, $r8
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:gpr = COPY $r8
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:gpr = COPY $r7
+  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:gpr = COPY $r6
+  ; CHECK-NEXT:   [[COPY3:%[0-9]+]]:gpr = COPY $r5
+  ; CHECK-NEXT:   [[COPY4:%[0-9]+]]:gpr = COPY $r4
+  ; CHECK-NEXT:   [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1
+  ; CHECK-NEXT:   [[ORI:%[0-9]+]]:gpr = ORI $r0, 1
+  ; CHECK-NEXT:   [[ANDI1:%[0-9]+]]:gpr = ANDI [[COPY2]], 1
+  ; CHECK-NEXT:   [[ANDI2:%[0-9]+]]:gpr = ANDI [[COPY1]], 1
+  ; CHECK-NEXT:   [[ANDI3:%[0-9]+]]:gpr = ANDI [[COPY]], 1
+  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:gpr = COPY $r0
+  ; CHECK-NEXT:   [[COPY6:%[0-9]+]]:gpr = COPY $r0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.2(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY7:%[0-9]+]]:gpr = COPY [[COPY5]]
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   successors: %bb.3(0x40000000), %bb.4(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   BEQZ [[ANDI]], %bb.4
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3:
+  ; CHECK-NEXT:   successors: %bb.9(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   PseudoBR %bb.9
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.4:
+  ; CHECK-NEXT:   successors: %bb.5(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.5:
+  ; CHECK-NEXT:   successors: %bb.7(0x7c000000), %bb.6(0x04000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   dead [[LD_D:%[0-9]+]]:gpr = LD_D $r0, 8
+  ; CHECK-NEXT:   dead [[LD_D1:%[0-9]+]]:gpr = LD_D $r0, 0
+  ; CHECK-NEXT:   BNEZ [[ANDI1]], %bb.7
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.6:
+  ; CHECK-NEXT:   successors: %bb.11(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY6:%[0-9]+]]:gpr = COPY $r0
+  ; CHECK-NEXT:   PseudoBR %bb.11
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.7:
+  ; CHECK-NEXT:   successors: %bb.8(0x7c000000), %bb.10(0x04000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   BEQZ [[ANDI2]], %bb.10
+  ; CHECK-NEXT:   PseudoBR %bb.8
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.8:
+  ; CHECK-NEXT:   successors: %bb.9(0x04000000), %bb.5(0x7c000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY6:%[0-9]+]]:gpr = ADDI_D [[COPY6]], 1
+  ; CHECK-NEXT:   BEQZ [[ANDI3]], %bb.5
+  ; CHECK-NEXT:   PseudoBR %bb.9
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.9:
+  ; CHECK-NEXT:   successors: %bb.12(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   ST_B $r0, [[COPY4]], 0
+  ; CHECK-NEXT:   PseudoBR %bb.12
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.10:
+  ; CHECK-NEXT:   successors: %bb.11(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY5:%[0-9]+]]:gpr = ADDI_D [[COPY6]], 1
+  ; CHECK-NEXT:   [[COPY6:%[0-9]+]]:gpr = COPY [[ORI]]
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.11:
+  ; CHECK-NEXT:   successors: %bb.12(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   ST_D $r0, [[COPY4]], 0
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.12:
+  ; CHECK-NEXT:   successors: %bb.2(0x7c000000), %bb.1(0x04000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   BEQ [[COPY7]], [[ORI]], %bb.2
+  ; CHECK-NEXT:   PseudoBR %bb.1
   bb.0:
     liveins: $r4, $r5, $r6, $r7, $r8
 

>From 4e0d1c281526c253edc36f932b3d88943e1a5a59 Mon Sep 17 00:00:00 2001
From: DianQK <dianqk at dianqk.net>
Date: Thu, 8 Feb 2024 21:05:20 +0800
Subject: [PATCH 3/5] fixup! Pre-commit test cases

---
 .../register-coalescer-crash-pr79718.mir      | 148 +++++++++---------
 1 file changed, 74 insertions(+), 74 deletions(-)

diff --git a/llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir b/llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir
index bfa8aba55dbc9..9bbb579b762e6 100644
--- a/llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir
+++ b/llvm/test/CodeGen/LoongArch/register-coalescer-crash-pr79718.mir
@@ -94,120 +94,120 @@ body:             |
   bb.0:
     liveins: $r4, $r5, $r6, $r7, $r8
 
-    %22:gpr = COPY killed $r8
-    %21:gpr = COPY killed $r7
-    %20:gpr = COPY killed $r6
-    %19:gpr = COPY killed $r5
-    %18:gpr = COPY killed $r4
-    %29:gpr = COPY $r0
-    %27:gpr = COPY killed %29
-    %30:gpr = ANDI killed %19, 1
-    %41:gpr = ORI $r0, 1
-    %35:gpr = ANDI killed %20, 1
-    %36:gpr = ANDI killed %21, 1
-    %39:gpr = ANDI killed %22, 1
-    %43:gpr = COPY %27
-    %44:gpr = COPY killed %27
-    %45:gpr = IMPLICIT_DEF
+    %0:gpr = COPY killed $r8
+    %1:gpr = COPY killed $r7
+    %2:gpr = COPY killed $r6
+    %3:gpr = COPY killed $r5
+    %4:gpr = COPY killed $r4
+    %5:gpr = COPY $r0
+    %6:gpr = COPY killed %5
+    %7:gpr = ANDI killed %3, 1
+    %8:gpr = ORI $r0, 1
+    %9:gpr = ANDI killed %2, 1
+    %10:gpr = ANDI killed %1, 1
+    %11:gpr = ANDI killed %0, 1
+    %12:gpr = COPY %6
+    %13:gpr = COPY killed %6
+    %14:gpr = IMPLICIT_DEF
 
   bb.1:
-    %2:gpr = COPY killed %45
-    %1:gpr = COPY killed %44
-    %0:gpr = COPY killed %43
-    %46:gpr = COPY %0
-    %47:gpr = COPY %1
-    %48:gpr = COPY killed %1
-    %49:gpr = COPY killed %2
+    %15:gpr = COPY killed %14
+    %16:gpr = COPY killed %13
+    %17:gpr = COPY killed %12
+    %18:gpr = COPY %17
+    %19:gpr = COPY %16
+    %20:gpr = COPY killed %16
+    %21:gpr = COPY killed %15
 
   bb.2:
     successors: %bb.3, %bb.4
 
-    %6:gpr = COPY killed %49
-    %5:gpr = COPY killed %48
-    %4:gpr = COPY killed %47
-    %3:gpr = COPY killed %46
-    BEQZ %30, %bb.4
+    %22:gpr = COPY killed %21
+    %23:gpr = COPY killed %20
+    %24:gpr = COPY killed %19
+    %25:gpr = COPY killed %18
+    BEQZ %7, %bb.4
 
   bb.3:
-    %51:gpr = COPY killed %4
-    %52:gpr = COPY killed %5
+    %26:gpr = COPY killed %24
+    %27:gpr = COPY killed %23
     PseudoBR %bb.9
 
   bb.4:
-    %50:gpr = COPY killed %5
+    %28:gpr = COPY killed %23
 
   bb.5:
     successors: %bb.7(0x7c000000), %bb.6(0x04000000)
 
-    %7:gpr = COPY killed %50
-    dead %33:gpr = LD_D $r0, 8
-    dead %34:gpr = LD_D $r0, 0
-    BNEZ %35, %bb.7
+    %29:gpr = COPY killed %28
+    dead %30:gpr = LD_D $r0, 8
+    dead %31:gpr = LD_D $r0, 0
+    BNEZ %9, %bb.7
 
   bb.6:
     %32:gpr = COPY $r0
-    %31:gpr = COPY killed %32
-    %53:gpr = COPY killed %31
-    %54:gpr = COPY killed %6
+    %33:gpr = COPY killed %32
+    %34:gpr = COPY killed %33
+    %35:gpr = COPY killed %22
     PseudoBR %bb.11
 
   bb.7:
     successors: %bb.8(0x7c000000), %bb.10(0x04000000)
 
-    BEQZ %36, %bb.10
+    BEQZ %10, %bb.10
     PseudoBR %bb.8
 
   bb.8:
     successors: %bb.9(0x04000000), %bb.5(0x7c000000)
 
-    %8:gpr = ADDI_D killed %7, 1
-    %50:gpr = COPY %8
-    %51:gpr = COPY %8
-    %52:gpr = COPY killed %8
-    BEQZ %39, %bb.5
+    %36:gpr = ADDI_D killed %29, 1
+    %28:gpr = COPY %36
+    %26:gpr = COPY %36
+    %27:gpr = COPY killed %36
+    BEQZ %11, %bb.5
     PseudoBR %bb.9
 
   bb.9:
-    %10:gpr = COPY killed %52
-    %9:gpr = COPY killed %51
-    %40:gpr = COPY $r0
-    ST_B killed %40, %18, 0
-    %55:gpr = COPY killed %3
-    %56:gpr = COPY killed %9
-    %57:gpr = COPY killed %10
-    %58:gpr = COPY killed %6
+    %37:gpr = COPY killed %27
+    %38:gpr = COPY killed %26
+    %39:gpr = COPY $r0
+    ST_B killed %39, %4, 0
+    %40:gpr = COPY killed %25
+    %41:gpr = COPY killed %38
+    %42:gpr = COPY killed %37
+    %43:gpr = COPY killed %22
     PseudoBR %bb.12
 
   bb.10:
-    %42:gpr = ADDI_D killed %7, 1
-    %53:gpr = COPY %41
-    %54:gpr = COPY killed %42
+    %44:gpr = ADDI_D killed %29, 1
+    %34:gpr = COPY %8
+    %35:gpr = COPY killed %44
 
   bb.11:
-    %13:gpr = COPY killed %54
-    %12:gpr = COPY killed %53
-    %38:gpr = COPY $r0
-    ST_D killed %38, %18, 0
-    %55:gpr = COPY %13
-    %56:gpr = COPY %12
-    %57:gpr = COPY killed %12
-    %58:gpr = COPY killed %13
+    %45:gpr = COPY killed %35
+    %46:gpr = COPY killed %34
+    %47:gpr = COPY $r0
+    ST_D killed %47, %4, 0
+    %40:gpr = COPY %45
+    %41:gpr = COPY %46
+    %42:gpr = COPY killed %46
+    %43:gpr = COPY killed %45
 
   bb.12:
     successors: %bb.2(0x7c000000), %bb.1(0x04000000)
 
-    %17:gpr = COPY killed %58
-    %16:gpr = COPY killed %57
-    %15:gpr = COPY killed %56
-    %14:gpr = COPY killed %55
-    %43:gpr = COPY %14
-    %44:gpr = COPY %15
-    %45:gpr = COPY %17
-    %46:gpr = COPY killed %14
-    %47:gpr = COPY killed %15
-    %48:gpr = COPY killed %16
-    %49:gpr = COPY killed %17
-    BEQ %0, %41, %bb.2
+    %48:gpr = COPY killed %43
+    %49:gpr = COPY killed %42
+    %50:gpr = COPY killed %41
+    %51:gpr = COPY killed %40
+    %12:gpr = COPY %51
+    %13:gpr = COPY %50
+    %14:gpr = COPY %48
+    %18:gpr = COPY killed %51
+    %19:gpr = COPY killed %50
+    %20:gpr = COPY killed %49
+    %21:gpr = COPY killed %48
+    BEQ %17, %8, %bb.2
     PseudoBR %bb.1
 
 ...

>From 0821515a306b548c0efa44658cbc6db1e7503e88 Mon Sep 17 00:00:00 2001
From: DianQK <dianqk at dianqk.net>
Date: Fri, 9 Feb 2024 14:20:24 +0800
Subject: [PATCH 4/5] [RegisterCoalescer] Clear instructions not recorded in
 `ErasedInstrs` but erased.

---
 llvm/lib/CodeGen/RegisterCoalescer.cpp        |  9 ++
 .../X86/PR71178-register-coalescer-crash.ll   | 95 +++++++++++++++++++
 2 files changed, 104 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/PR71178-register-coalescer-crash.ll

diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index d3125fba67206..233c86af1b736 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -4003,6 +4003,15 @@ copyCoalesceWorkList(MutableArrayRef<MachineInstr*> CurrList) {
     if (Success || !Again)
       MI = nullptr;
   }
+  // Clear instructions not recorded in `ErasedInstrs` but erased.
+  if (!CurrentErasedInstrs.empty()) {
+    for (MachineInstr *&MI : CurrList)
+      if (MI && CurrentErasedInstrs.count(MI))
+        MI = nullptr;
+    for (MachineInstr *&MI : WorkList)
+      if (MI && CurrentErasedInstrs.count(MI))
+        MI = nullptr;
+  }
   return Progress;
 }
 
diff --git a/llvm/test/CodeGen/X86/PR71178-register-coalescer-crash.ll b/llvm/test/CodeGen/X86/PR71178-register-coalescer-crash.ll
new file mode 100644
index 0000000000000..ba067a89a1beb
--- /dev/null
+++ b/llvm/test/CodeGen/X86/PR71178-register-coalescer-crash.ll
@@ -0,0 +1,95 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc < %s -mtriple=x86_64 -- | FileCheck %s
+
+define i32 @h(i1 %0, i32 %1) {
+; CHECK-LABEL: h:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movl $1, %eax
+; CHECK-NEXT:    movabsq $9166129423, %rcx # imm = 0x22258090F
+; CHECK-NEXT:    xorl %edx, %edx
+; CHECK-NEXT:    jmp .LBB0_1
+; CHECK-NEXT:    .p2align 4, 0x90
+; CHECK-NEXT:  .LBB0_9: # in Loop: Header=BB0_1 Depth=1
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    testb $1, %dil
+; CHECK-NEXT:    jne .LBB0_10
+; CHECK-NEXT:  .LBB0_1: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:    testq %rdx, %rdx
+; CHECK-NEXT:    jne .LBB0_2
+; CHECK-NEXT:  # %bb.7: # in Loop: Header=BB0_1 Depth=1
+; CHECK-NEXT:    testb $1, %dil
+; CHECK-NEXT:    jne .LBB0_9
+; CHECK-NEXT:  # %bb.8: # in Loop: Header=BB0_1 Depth=1
+; CHECK-NEXT:    movq %rcx, %rdx
+; CHECK-NEXT:    jmp .LBB0_9
+; CHECK-NEXT:  .LBB0_2: # in Loop: Header=BB0_1 Depth=1
+; CHECK-NEXT:    testb $1, %dil
+; CHECK-NEXT:    testb $1, %dil
+; CHECK-NEXT:    je .LBB0_4
+; CHECK-NEXT:  # %bb.3: # in Loop: Header=BB0_1 Depth=1
+; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:  .LBB0_4: # in Loop: Header=BB0_1 Depth=1
+; CHECK-NEXT:    cmpl $1, %esi
+; CHECK-NEXT:    je .LBB0_1
+; CHECK-NEXT:  # %bb.5:
+; CHECK-NEXT:    movl %eax, %r8d
+; CHECK-NEXT:    testl %esi, %esi
+; CHECK-NEXT:    movl %esi, %eax
+; CHECK-NEXT:    jne .LBB0_6
+; CHECK-NEXT:  .LBB0_10:
+; CHECK-NEXT:    retq
+; CHECK-NEXT:  .LBB0_6: # %.loopexit1
+; CHECK-NEXT:    movl %r8d, %eax
+; CHECK-NEXT:    retq
+  br label %3
+
+3:                                                ; preds = %16, %2
+  %4 = phi i64 [ %7, %16 ], [ 0, %2 ]
+  %5 = phi i32 [ %17, %16 ], [ 1, %2 ]
+  br label %6
+
+6:                                                ; preds = %20, %3
+  %7 = phi i64 [ %21, %20 ], [ %4, %3 ]
+  %8 = phi i64 [ %22, %20 ], [ %4, %3 ]
+  %9 = phi i32 [ 0, %20 ], [ %5, %3 ]
+  %10 = icmp eq i64 %8, 0
+  br i1 %10, label %18, label %11
+
+11:                                               ; preds = %6
+  br i1 %0, label %14, label %12
+
+12:                                               ; preds = %11
+  %13 = sdiv i64 0, 0
+  br label %14
+
+14:                                               ; preds = %12, %11
+  br i1 %0, label %15, label %16
+
+15:                                               ; preds = %14
+  br label %16
+
+16:                                               ; preds = %15, %14
+  %17 = phi i32 [ 0, %15 ], [ %9, %14 ]
+  switch i32 %1, label %24 [
+    i32 0, label %23
+    i32 1, label %3
+  ]
+
+18:                                               ; preds = %6
+  br i1 %0, label %20, label %19
+
+19:                                               ; preds = %18
+  br label %20
+
+20:                                               ; preds = %19, %18
+  %21 = phi i64 [ 9166129423, %19 ], [ %7, %18 ]
+  %22 = phi i64 [ 9166129423, %19 ], [ %8, %18 ]
+  br i1 %0, label %24, label %6
+
+23:                                               ; preds = %16
+  br label %24
+
+24:                                               ; preds = %23, %20, %16
+  %25 = phi i32 [ %1, %23 ], [ %17, %16 ], [ 0, %20 ]
+  ret i32 %25
+}

>From a27d5b38e5c2a082bf7c132b7ef08120c96e092d Mon Sep 17 00:00:00 2001
From: DianQK <dianqk at dianqk.net>
Date: Fri, 9 Feb 2024 14:41:41 +0800
Subject: [PATCH 5/5] fixup! [RegisterCoalescer] Clear instructions not
 recorded in `ErasedInstrs` but erased.

---
 llvm/lib/CodeGen/RegisterCoalescer.cpp        |   6 +-
 .../X86/PR71178-register-coalescer-crash.ll   | 108 ++++++++++--------
 2 files changed, 62 insertions(+), 52 deletions(-)

diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 233c86af1b736..7e9c992031f8d 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -4005,12 +4005,14 @@ copyCoalesceWorkList(MutableArrayRef<MachineInstr*> CurrList) {
   }
   // Clear instructions not recorded in `ErasedInstrs` but erased.
   if (!CurrentErasedInstrs.empty()) {
-    for (MachineInstr *&MI : CurrList)
+    for (MachineInstr *&MI : CurrList) {
       if (MI && CurrentErasedInstrs.count(MI))
         MI = nullptr;
-    for (MachineInstr *&MI : WorkList)
+    }
+    for (MachineInstr *&MI : WorkList) {
       if (MI && CurrentErasedInstrs.count(MI))
         MI = nullptr;
+    }
   }
   return Progress;
 }
diff --git a/llvm/test/CodeGen/X86/PR71178-register-coalescer-crash.ll b/llvm/test/CodeGen/X86/PR71178-register-coalescer-crash.ll
index ba067a89a1beb..0ce346f7c2e02 100644
--- a/llvm/test/CodeGen/X86/PR71178-register-coalescer-crash.ll
+++ b/llvm/test/CodeGen/X86/PR71178-register-coalescer-crash.ll
@@ -1,95 +1,103 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
 ; RUN: llc < %s -mtriple=x86_64 -- | FileCheck %s
 
-define i32 @h(i1 %0, i32 %1) {
+define i32 @h(i1 %arg, i32 %arg1) {
 ; CHECK-LABEL: h:
-; CHECK:       # %bb.0:
+; CHECK:       # %bb.0: # %bb
 ; CHECK-NEXT:    movl $1, %eax
 ; CHECK-NEXT:    movabsq $9166129423, %rcx # imm = 0x22258090F
 ; CHECK-NEXT:    xorl %edx, %edx
 ; CHECK-NEXT:    jmp .LBB0_1
 ; CHECK-NEXT:    .p2align 4, 0x90
-; CHECK-NEXT:  .LBB0_9: # in Loop: Header=BB0_1 Depth=1
+; CHECK-NEXT:  .LBB0_9: # %bb18
+; CHECK-NEXT:    # in Loop: Header=BB0_1 Depth=1
 ; CHECK-NEXT:    xorl %eax, %eax
 ; CHECK-NEXT:    testb $1, %dil
 ; CHECK-NEXT:    jne .LBB0_10
-; CHECK-NEXT:  .LBB0_1: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:  .LBB0_1: # %bb4
+; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
 ; CHECK-NEXT:    testq %rdx, %rdx
 ; CHECK-NEXT:    jne .LBB0_2
-; CHECK-NEXT:  # %bb.7: # in Loop: Header=BB0_1 Depth=1
+; CHECK-NEXT:  # %bb.7: # %bb16
+; CHECK-NEXT:    # in Loop: Header=BB0_1 Depth=1
 ; CHECK-NEXT:    testb $1, %dil
 ; CHECK-NEXT:    jne .LBB0_9
-; CHECK-NEXT:  # %bb.8: # in Loop: Header=BB0_1 Depth=1
+; CHECK-NEXT:  # %bb.8: # %bb17
+; CHECK-NEXT:    # in Loop: Header=BB0_1 Depth=1
 ; CHECK-NEXT:    movq %rcx, %rdx
 ; CHECK-NEXT:    jmp .LBB0_9
-; CHECK-NEXT:  .LBB0_2: # in Loop: Header=BB0_1 Depth=1
+; CHECK-NEXT:  .LBB0_2: # %bb9
+; CHECK-NEXT:    # in Loop: Header=BB0_1 Depth=1
 ; CHECK-NEXT:    testb $1, %dil
 ; CHECK-NEXT:    testb $1, %dil
 ; CHECK-NEXT:    je .LBB0_4
-; CHECK-NEXT:  # %bb.3: # in Loop: Header=BB0_1 Depth=1
+; CHECK-NEXT:  # %bb.3: # %bb13
+; CHECK-NEXT:    # in Loop: Header=BB0_1 Depth=1
 ; CHECK-NEXT:    xorl %eax, %eax
-; CHECK-NEXT:  .LBB0_4: # in Loop: Header=BB0_1 Depth=1
+; CHECK-NEXT:  .LBB0_4: # %bb14
+; CHECK-NEXT:    # in Loop: Header=BB0_1 Depth=1
 ; CHECK-NEXT:    cmpl $1, %esi
 ; CHECK-NEXT:    je .LBB0_1
-; CHECK-NEXT:  # %bb.5:
+; CHECK-NEXT:  # %bb.5: # %bb14
 ; CHECK-NEXT:    movl %eax, %r8d
 ; CHECK-NEXT:    testl %esi, %esi
 ; CHECK-NEXT:    movl %esi, %eax
 ; CHECK-NEXT:    jne .LBB0_6
-; CHECK-NEXT:  .LBB0_10:
+; CHECK-NEXT:  .LBB0_10: # %bb22
 ; CHECK-NEXT:    retq
-; CHECK-NEXT:  .LBB0_6: # %.loopexit1
+; CHECK-NEXT:  .LBB0_6: # %bb22.loopexit1
 ; CHECK-NEXT:    movl %r8d, %eax
 ; CHECK-NEXT:    retq
-  br label %3
+bb:
+  br label %bb2
 
-3:                                                ; preds = %16, %2
-  %4 = phi i64 [ %7, %16 ], [ 0, %2 ]
-  %5 = phi i32 [ %17, %16 ], [ 1, %2 ]
-  br label %6
+bb2:                                              ; preds = %bb14, %bb
+  %i = phi i64 [ %i5, %bb14 ], [ 0, %bb ]
+  %i3 = phi i32 [ %i15, %bb14 ], [ 1, %bb ]
+  br label %bb4
 
-6:                                                ; preds = %20, %3
-  %7 = phi i64 [ %21, %20 ], [ %4, %3 ]
-  %8 = phi i64 [ %22, %20 ], [ %4, %3 ]
-  %9 = phi i32 [ 0, %20 ], [ %5, %3 ]
-  %10 = icmp eq i64 %8, 0
-  br i1 %10, label %18, label %11
+bb4:                                              ; preds = %bb18, %bb2
+  %i5 = phi i64 [ %i19, %bb18 ], [ %i, %bb2 ]
+  %i6 = phi i64 [ %i20, %bb18 ], [ %i, %bb2 ]
+  %i7 = phi i32 [ 0, %bb18 ], [ %i3, %bb2 ]
+  %i8 = icmp eq i64 %i6, 0
+  br i1 %i8, label %bb16, label %bb9
 
-11:                                               ; preds = %6
-  br i1 %0, label %14, label %12
+bb9:                                              ; preds = %bb4
+  br i1 %arg, label %bb12, label %bb10
 
-12:                                               ; preds = %11
-  %13 = sdiv i64 0, 0
-  br label %14
+bb10:                                             ; preds = %bb9
+  %i11 = sdiv i64 0, 0
+  br label %bb12
 
-14:                                               ; preds = %12, %11
-  br i1 %0, label %15, label %16
+bb12:                                             ; preds = %bb10, %bb9
+  br i1 %arg, label %bb13, label %bb14
 
-15:                                               ; preds = %14
-  br label %16
+bb13:                                             ; preds = %bb12
+  br label %bb14
 
-16:                                               ; preds = %15, %14
-  %17 = phi i32 [ 0, %15 ], [ %9, %14 ]
-  switch i32 %1, label %24 [
-    i32 0, label %23
-    i32 1, label %3
+bb14:                                             ; preds = %bb13, %bb12
+  %i15 = phi i32 [ 0, %bb13 ], [ %i7, %bb12 ]
+  switch i32 %arg1, label %bb22 [
+    i32 0, label %bb21
+    i32 1, label %bb2
   ]
 
-18:                                               ; preds = %6
-  br i1 %0, label %20, label %19
+bb16:                                             ; preds = %bb4
+  br i1 %arg, label %bb18, label %bb17
 
-19:                                               ; preds = %18
-  br label %20
+bb17:                                             ; preds = %bb16
+  br label %bb18
 
-20:                                               ; preds = %19, %18
-  %21 = phi i64 [ 9166129423, %19 ], [ %7, %18 ]
-  %22 = phi i64 [ 9166129423, %19 ], [ %8, %18 ]
-  br i1 %0, label %24, label %6
+bb18:                                             ; preds = %bb17, %bb16
+  %i19 = phi i64 [ 9166129423, %bb17 ], [ %i5, %bb16 ]
+  %i20 = phi i64 [ 9166129423, %bb17 ], [ %i6, %bb16 ]
+  br i1 %arg, label %bb22, label %bb4
 
-23:                                               ; preds = %16
-  br label %24
+bb21:                                             ; preds = %bb14
+  br label %bb22
 
-24:                                               ; preds = %23, %20, %16
-  %25 = phi i32 [ %1, %23 ], [ %17, %16 ], [ 0, %20 ]
-  ret i32 %25
+bb22:                                             ; preds = %bb21, %bb18, %bb14
+  %i23 = phi i32 [ %arg1, %bb21 ], [ %i15, %bb14 ], [ 0, %bb18 ]
+  ret i32 %i23
 }



More information about the llvm-commits mailing list