[llvm] [RegisterCoalescer] Skip the pattern that can't resolve (PR #71024)
Piyou Chen via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 1 23:28:21 PDT 2023
https://github.com/BeMg created https://github.com/llvm/llvm-project/pull/71024
https://github.com/llvm/llvm-project/issues/71023
Skip the situation that will trigger assertion.
The pruneValues can't handle the `early-clobber` in edge, but it will be mark as `CR_Replace`
```
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
```
In result, it make LiveInterval try to join the overlap segments with different VNIInfo.
This patch find this pattern and skip in beginning.
>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] [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
+...
More information about the llvm-commits
mailing list