[llvm] [RegisterCoalescer] Skip CR_Replace pattern that has early-clobber in segment's edge (PR #71024)

Piyou Chen via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 4 22:47:36 PDT 2023


https://github.com/BeMg updated https://github.com/llvm/llvm-project/pull/71024

>From 95dbe42be96903dcaeedb5b9878339ba29008f78 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Wed, 1 Nov 2023 22:41:56 -0700
Subject: [PATCH 1/3] [RegisterCoalescer] Skip the pattern that can't resolve

---
 llvm/lib/CodeGen/RegisterCoalescer.cpp        | 39 +++++++++++
 .../reg-coalescing-replace-not-resolvable.mir | 66 +++++++++++++++++++
 2 files changed, 105 insertions(+)
 create mode 100644 llvm/test/CodeGen/RISCV/reg-coalescing-replace-not-resolvable.mir

diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 9858482cd51b4a7..c962668d314c0fd 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -2612,6 +2612,8 @@ class JoinVals {
   ConflictResolution getResolution(unsigned Num) const {
     return Vals[Num].Resolution;
   }
+
+  bool canCRReplaceBeResolved(JoinVals &Other);
 };
 
 } // end anonymous namespace
@@ -3481,6 +3483,39 @@ void JoinVals::eraseInstrs(SmallPtrSetImpl<MachineInstr*> &ErasedInstrs,
   }
 }
 
+// If the overlapping segment all be mark as CR_Replace resolution, 
+// but can't be resolved resolveConflicts/pruneValues function.
+// 
+// This function target this particular pattern and make joinVReg fail. 
+//
+// For example: 
+//   LHS: %12 [32r,80r:0)[96r,240r:1) 0 at 32r 1 at 96r 
+//   RHS: %17 [240e,288r:1) 0 at 48r 1 at 240e
+// [96r,240r:2) and [240e,288r:1) both be mark as CR_Replace, 
+// but does't be resolved after pruneValues.
+// 
+bool JoinVals::canCRReplaceBeResolved(JoinVals &Other) {
+  for (auto Seg : LR.segments) {
+    for (auto OtherSeg : Other.LR.segments) {
+      int NewVNInoSeg = getAssignments()[Seg.valno->id];
+      int NewVNInoOtherSeg = Other.getAssignments()[OtherSeg.valno->id];
+
+      if (NewVNInoSeg == NewVNInoOtherSeg)
+        continue;
+
+      if (!(getResolution(Seg.valno->id) == CR_Replace &&
+            Other.getResolution(OtherSeg.valno->id) == CR_Replace))
+        continue;
+
+      if (Seg.contains(OtherSeg.start) && OtherSeg.start.isEarlyClobber() &&
+          !Seg.end.isEarlyClobber() &&
+          (Seg.end.getBaseIndex() == OtherSeg.start.getBaseIndex()))
+        return false;
+    }
+  }
+  return true;
+}
+
 void RegisterCoalescer::joinSubRegRanges(LiveRange &LRange, LiveRange &RRange,
                                          LaneBitmask LaneMask,
                                          const CoalescerPair &CP) {
@@ -3599,6 +3634,10 @@ bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
   if (!LHSVals.resolveConflicts(RHSVals) || !RHSVals.resolveConflicts(LHSVals))
     return false;
 
+  // Some CR_Replace can't be solved by pruneValues. Early exit here.
+  if (!LHSVals.canCRReplaceBeResolved(RHSVals) || !RHSVals.canCRReplaceBeResolved(LHSVals))
+    return false;
+
   // All clear, the live ranges can be merged.
   if (RHS.hasSubRanges() || LHS.hasSubRanges()) {
     BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
diff --git a/llvm/test/CodeGen/RISCV/reg-coalescing-replace-not-resolvable.mir b/llvm/test/CodeGen/RISCV/reg-coalescing-replace-not-resolvable.mir
new file mode 100644
index 000000000000000..a3f1ac7f0015602
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/reg-coalescing-replace-not-resolvable.mir
@@ -0,0 +1,66 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3
+# RUN: llc  %s -o - -mtriple=riscv64 -mattr=+v -run-pass=register-coalescer \
+# RUN:  -verify-machineinstrs | FileCheck %s
+
+---
+name:            main
+tracksRegLiveness: true
+body:             |
+  ; CHECK-LABEL: name: main
+  ; CHECK: bb.0:
+  ; CHECK-NEXT:   successors: %bb.3(0x40000000), %bb.1(0x40000000)
+  ; CHECK-NEXT:   liveins: $x10, $v8, $v10
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   dead [[DEF:%[0-9]+]]:gpr = IMPLICIT_DEF
+  ; CHECK-NEXT:   undef [[PseudoVMV_V_I_M1_:%[0-9]+]].sub_vrm1_0:vrn6m1nov0 = PseudoVMV_V_I_M1 undef [[PseudoVMV_V_I_M1_]].sub_vrm1_0, 0, -1, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
+  ; CHECK-NEXT:   undef [[DEF1:%[0-9]+]].sub_vrm1_5:vrn6m1 = IMPLICIT_DEF
+  ; CHECK-NEXT:   [[PseudoVMV_V_I_M1_:%[0-9]+]].sub_vrm1_3:vrn6m1nov0 = COPY [[DEF1]].sub_vrm1_5
+  ; CHECK-NEXT:   [[PseudoVMV_V_I_M1_:%[0-9]+]].sub_vrm1_4:vrn6m1nov0 = COPY undef [[PseudoVMV_V_I_M1_]].sub_vrm1_0
+  ; CHECK-NEXT:   BNE undef [[DEF]], $x0, %bb.3
+  ; CHECK-NEXT:   PseudoBR %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1:
+  ; CHECK-NEXT:   successors: %bb.3(0x40000000), %bb.2(0x40000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   BNE undef [[DEF]], $x0, %bb.3
+  ; CHECK-NEXT:   PseudoBR %bb.2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2:
+  ; CHECK-NEXT:   successors: %bb.3(0x80000000)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3:
+  ; CHECK-NEXT:   dead [[DEF2:%[0-9]+]]:vr = IMPLICIT_DEF
+  ; CHECK-NEXT:   early-clobber [[DEF1]].sub_vrm1_0:vrn6m1 = PseudoVRGATHER_VI_M1 undef [[DEF1]].sub_vrm1_0, [[PseudoVMV_V_I_M1_]].sub_vrm1_0, 0, 0, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
+  ; CHECK-NEXT:   PseudoVSSEG6E8_V_M1_MASK [[DEF1]], undef [[DEF]], killed undef $v0, 0, 3 /* e8 */, implicit $vl, implicit $vtype :: (store unknown-size, align 1)
+  ; CHECK-NEXT:   PseudoRET
+  bb.0:
+    successors: %bb.5(0x40000000), %bb.3(0x40000000)
+    liveins: $x10, $v8, $v10
+
+    %32:gpr = IMPLICIT_DEF
+    %10:vrnov0 = PseudoVMV_V_I_M1 undef %10, 0, -1, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
+    %11:vrnov0 = IMPLICIT_DEF
+    undef %12.sub_vrm1_0:vrn6m1nov0 = COPY undef %10
+    %12.sub_vrm1_3:vrn6m1nov0 = COPY %11
+    %12.sub_vrm1_4:vrn6m1nov0 = COPY undef %10
+    BNE undef %32, $x0, %bb.5
+    PseudoBR %bb.3
+
+  bb.3:
+    successors: %bb.5(0x40000000), %bb.4(0x40000000)
+
+    BNE killed undef %32, $x0, %bb.5
+    PseudoBR %bb.4
+
+  bb.4:
+    successors: %bb.5(0x80000000)
+
+  bb.5:
+    %1:vr = IMPLICIT_DEF
+    early-clobber %1:vr = PseudoVRGATHER_VI_M1 undef %1, killed %10, 0, 0, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
+    undef %17.sub_vrm1_0:vrn6m1 = COPY killed %1
+    %17.sub_vrm1_5:vrn6m1 = COPY killed %11
+    PseudoVSSEG6E8_V_M1_MASK killed %17, undef %32, killed undef $v0, 0, 3 /* e8 */, implicit $vl, implicit $vtype :: (store unknown-size, align 1)
+    PseudoRET
+...

>From 245b251a7e126ce1c026ac5df5455a897d44293a Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Sat, 4 Nov 2023 22:40:38 -0700
Subject: [PATCH 2/3] Fix format

---
 llvm/lib/CodeGen/RegisterCoalescer.cpp | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index c962668d314c0fd..8593606882b2805 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -3483,17 +3483,17 @@ void JoinVals::eraseInstrs(SmallPtrSetImpl<MachineInstr*> &ErasedInstrs,
   }
 }
 
-// If the overlapping segment all be mark as CR_Replace resolution, 
+// If the overlapping segment all be mark as CR_Replace resolution,
 // but can't be resolved resolveConflicts/pruneValues function.
-// 
-// This function target this particular pattern and make joinVReg fail. 
 //
-// For example: 
-//   LHS: %12 [32r,80r:0)[96r,240r:1) 0 at 32r 1 at 96r 
+// This function target this particular pattern and make joinVReg fail.
+//
+// For example:
+//   LHS: %12 [32r,80r:0)[96r,240r:1) 0 at 32r 1 at 96r
 //   RHS: %17 [240e,288r:1) 0 at 48r 1 at 240e
-// [96r,240r:2) and [240e,288r:1) both be mark as CR_Replace, 
+// [96r,240r:2) and [240e,288r:1) both be mark as CR_Replace,
 // but does't be resolved after pruneValues.
-// 
+//
 bool JoinVals::canCRReplaceBeResolved(JoinVals &Other) {
   for (auto Seg : LR.segments) {
     for (auto OtherSeg : Other.LR.segments) {
@@ -3635,7 +3635,8 @@ bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
     return false;
 
   // Some CR_Replace can't be solved by pruneValues. Early exit here.
-  if (!LHSVals.canCRReplaceBeResolved(RHSVals) || !RHSVals.canCRReplaceBeResolved(LHSVals))
+  if (!LHSVals.canCRReplaceBeResolved(RHSVals) ||
+      !RHSVals.canCRReplaceBeResolved(LHSVals))
     return false;
 
   // All clear, the live ranges can be merged.

>From 1f1489ce368d6dadb471df9700a1cc955696a47d Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Sat, 4 Nov 2023 22:47:06 -0700
Subject: [PATCH 3/3] Update RegNumber

---
 .../reg-coalescing-replace-not-resolvable.mir | 42 +++++++++----------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/llvm/test/CodeGen/RISCV/reg-coalescing-replace-not-resolvable.mir b/llvm/test/CodeGen/RISCV/reg-coalescing-replace-not-resolvable.mir
index a3f1ac7f0015602..d82ac4bc7780a73 100644
--- a/llvm/test/CodeGen/RISCV/reg-coalescing-replace-not-resolvable.mir
+++ b/llvm/test/CodeGen/RISCV/reg-coalescing-replace-not-resolvable.mir
@@ -35,32 +35,32 @@ body:             |
   ; CHECK-NEXT:   PseudoVSSEG6E8_V_M1_MASK [[DEF1]], undef [[DEF]], killed undef $v0, 0, 3 /* e8 */, implicit $vl, implicit $vtype :: (store unknown-size, align 1)
   ; CHECK-NEXT:   PseudoRET
   bb.0:
-    successors: %bb.5(0x40000000), %bb.3(0x40000000)
+    successors: %bb.3(0x40000000), %bb.1(0x40000000)
     liveins: $x10, $v8, $v10
 
-    %32:gpr = IMPLICIT_DEF
-    %10:vrnov0 = PseudoVMV_V_I_M1 undef %10, 0, -1, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
-    %11:vrnov0 = IMPLICIT_DEF
-    undef %12.sub_vrm1_0:vrn6m1nov0 = COPY undef %10
-    %12.sub_vrm1_3:vrn6m1nov0 = COPY %11
-    %12.sub_vrm1_4:vrn6m1nov0 = COPY undef %10
-    BNE undef %32, $x0, %bb.5
-    PseudoBR %bb.3
+    %0:gpr = IMPLICIT_DEF
+    %1:vrnov0 = PseudoVMV_V_I_M1 undef %1, 0, -1, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
+    %2:vrnov0 = IMPLICIT_DEF
+    undef %3.sub_vrm1_0:vrn6m1nov0 = COPY undef %1
+    %3.sub_vrm1_3:vrn6m1nov0 = COPY %2
+    %3.sub_vrm1_4:vrn6m1nov0 = COPY undef %1
+    BNE undef %0, $x0, %bb.3
+    PseudoBR %bb.1
 
-  bb.3:
-    successors: %bb.5(0x40000000), %bb.4(0x40000000)
+  bb.1:
+    successors: %bb.3(0x40000000), %bb.2(0x40000000)
 
-    BNE killed undef %32, $x0, %bb.5
-    PseudoBR %bb.4
+    BNE killed undef %0, $x0, %bb.3
+    PseudoBR %bb.2
 
-  bb.4:
-    successors: %bb.5(0x80000000)
+  bb.2:
+    successors: %bb.3(0x80000000)
 
-  bb.5:
-    %1:vr = IMPLICIT_DEF
-    early-clobber %1:vr = PseudoVRGATHER_VI_M1 undef %1, killed %10, 0, 0, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
-    undef %17.sub_vrm1_0:vrn6m1 = COPY killed %1
-    %17.sub_vrm1_5:vrn6m1 = COPY killed %11
-    PseudoVSSEG6E8_V_M1_MASK killed %17, undef %32, killed undef $v0, 0, 3 /* e8 */, implicit $vl, implicit $vtype :: (store unknown-size, align 1)
+  bb.3:
+    %4:vr = IMPLICIT_DEF
+    early-clobber %4:vr = PseudoVRGATHER_VI_M1 undef %4, killed %1, 0, 0, 3 /* e8 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
+    undef %5.sub_vrm1_0:vrn6m1 = COPY killed %4
+    %5.sub_vrm1_5:vrn6m1 = COPY killed %2
+    PseudoVSSEG6E8_V_M1_MASK killed %5, undef %0, killed undef $v0, 0, 3 /* e8 */, implicit $vl, implicit $vtype :: (store unknown-size, align 1)
     PseudoRET
 ...



More information about the llvm-commits mailing list