Skip to content

Commit 95b14da

Browse files
authored
[RegisterCoalescer] Clear instructions not recorded in ErasedInstrs but erased (#79820)
Fixes #79718. Fixes #71178. The same instructions may exist in an iteration. We cannot immediately delete instructions in `ErasedInstrs`.
1 parent b2cd50d commit 95b14da

File tree

3 files changed

+338
-5
lines changed

3 files changed

+338
-5
lines changed

llvm/lib/CodeGen/RegisterCoalescer.cpp

+22-5
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,8 @@ namespace {
236236
/// was successfully coalesced away. If it is not currently possible to
237237
/// coalesce this interval, but it may be possible if other things get
238238
/// coalesced, then it returns true by reference in 'Again'.
239-
bool joinCopy(MachineInstr *CopyMI, bool &Again);
239+
bool joinCopy(MachineInstr *CopyMI, bool &Again,
240+
SmallPtrSetImpl<MachineInstr *> &CurrentErasedInstrs);
240241

241242
/// Attempt to join these two intervals. On failure, this
242243
/// returns false. The output "SrcInt" will not have been modified, so we
@@ -1964,7 +1965,9 @@ void RegisterCoalescer::setUndefOnPrunedSubRegUses(LiveInterval &LI,
19641965
LIS->shrinkToUses(&LI);
19651966
}
19661967

1967-
bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
1968+
bool RegisterCoalescer::joinCopy(
1969+
MachineInstr *CopyMI, bool &Again,
1970+
SmallPtrSetImpl<MachineInstr *> &CurrentErasedInstrs) {
19681971
Again = false;
19691972
LLVM_DEBUG(dbgs() << LIS->getInstructionIndex(*CopyMI) << '\t' << *CopyMI);
19701973

@@ -2156,7 +2159,9 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
21562159
// CopyMI has been erased by joinIntervals at this point. Remove it from
21572160
// ErasedInstrs since copyCoalesceWorkList() won't add a successful join back
21582161
// to the work list. This keeps ErasedInstrs from growing needlessly.
2159-
ErasedInstrs.erase(CopyMI);
2162+
if (ErasedInstrs.erase(CopyMI))
2163+
// But we may encounter the instruction again in this iteration.
2164+
CurrentErasedInstrs.insert(CopyMI);
21602165

21612166
// Rewrite all SrcReg operands to DstReg.
21622167
// Also update DstReg operands to include DstIdx if it is set.
@@ -3982,21 +3987,33 @@ void RegisterCoalescer::lateLiveIntervalUpdate() {
39823987
bool RegisterCoalescer::
39833988
copyCoalesceWorkList(MutableArrayRef<MachineInstr*> CurrList) {
39843989
bool Progress = false;
3990+
SmallPtrSet<MachineInstr *, 4> CurrentErasedInstrs;
39853991
for (MachineInstr *&MI : CurrList) {
39863992
if (!MI)
39873993
continue;
39883994
// Skip instruction pointers that have already been erased, for example by
39893995
// dead code elimination.
3990-
if (ErasedInstrs.count(MI)) {
3996+
if (ErasedInstrs.count(MI) || CurrentErasedInstrs.count(MI)) {
39913997
MI = nullptr;
39923998
continue;
39933999
}
39944000
bool Again = false;
3995-
bool Success = joinCopy(MI, Again);
4001+
bool Success = joinCopy(MI, Again, CurrentErasedInstrs);
39964002
Progress |= Success;
39974003
if (Success || !Again)
39984004
MI = nullptr;
39994005
}
4006+
// Clear instructions not recorded in `ErasedInstrs` but erased.
4007+
if (!CurrentErasedInstrs.empty()) {
4008+
for (MachineInstr *&MI : CurrList) {
4009+
if (MI && CurrentErasedInstrs.count(MI))
4010+
MI = nullptr;
4011+
}
4012+
for (MachineInstr *&MI : WorkList) {
4013+
if (MI && CurrentErasedInstrs.count(MI))
4014+
MI = nullptr;
4015+
}
4016+
}
40004017
return Progress;
40014018
}
40024019

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
2+
# RUN: llc -o - %s -mtriple=loongarch64 \
3+
# RUN: -run-pass=register-coalescer -join-liveintervals=1 -join-splitedges=0 | FileCheck %s
4+
5+
---
6+
name: foo
7+
tracksRegLiveness: true
8+
body: |
9+
; CHECK-LABEL: name: foo
10+
; CHECK: bb.0:
11+
; CHECK-NEXT: successors: %bb.1(0x80000000)
12+
; CHECK-NEXT: liveins: $r4, $r5, $r6, $r7, $r8
13+
; CHECK-NEXT: {{ $}}
14+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $r8
15+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $r7
16+
; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $r6
17+
; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $r5
18+
; CHECK-NEXT: [[COPY4:%[0-9]+]]:gpr = COPY $r4
19+
; CHECK-NEXT: [[ANDI:%[0-9]+]]:gpr = ANDI [[COPY3]], 1
20+
; CHECK-NEXT: [[ORI:%[0-9]+]]:gpr = ORI $r0, 1
21+
; CHECK-NEXT: [[ANDI1:%[0-9]+]]:gpr = ANDI [[COPY2]], 1
22+
; CHECK-NEXT: [[ANDI2:%[0-9]+]]:gpr = ANDI [[COPY1]], 1
23+
; CHECK-NEXT: [[ANDI3:%[0-9]+]]:gpr = ANDI [[COPY]], 1
24+
; CHECK-NEXT: [[COPY5:%[0-9]+]]:gpr = COPY $r0
25+
; CHECK-NEXT: [[COPY6:%[0-9]+]]:gpr = COPY $r0
26+
; CHECK-NEXT: {{ $}}
27+
; CHECK-NEXT: bb.1:
28+
; CHECK-NEXT: successors: %bb.2(0x80000000)
29+
; CHECK-NEXT: {{ $}}
30+
; CHECK-NEXT: [[COPY7:%[0-9]+]]:gpr = COPY [[COPY5]]
31+
; CHECK-NEXT: {{ $}}
32+
; CHECK-NEXT: bb.2:
33+
; CHECK-NEXT: successors: %bb.3(0x40000000), %bb.4(0x40000000)
34+
; CHECK-NEXT: {{ $}}
35+
; CHECK-NEXT: BEQZ [[ANDI]], %bb.4
36+
; CHECK-NEXT: {{ $}}
37+
; CHECK-NEXT: bb.3:
38+
; CHECK-NEXT: successors: %bb.9(0x80000000)
39+
; CHECK-NEXT: {{ $}}
40+
; CHECK-NEXT: PseudoBR %bb.9
41+
; CHECK-NEXT: {{ $}}
42+
; CHECK-NEXT: bb.4:
43+
; CHECK-NEXT: successors: %bb.5(0x80000000)
44+
; CHECK-NEXT: {{ $}}
45+
; CHECK-NEXT: {{ $}}
46+
; CHECK-NEXT: bb.5:
47+
; CHECK-NEXT: successors: %bb.7(0x7c000000), %bb.6(0x04000000)
48+
; CHECK-NEXT: {{ $}}
49+
; CHECK-NEXT: dead [[LD_D:%[0-9]+]]:gpr = LD_D $r0, 8
50+
; CHECK-NEXT: dead [[LD_D1:%[0-9]+]]:gpr = LD_D $r0, 0
51+
; CHECK-NEXT: BNEZ [[ANDI1]], %bb.7
52+
; CHECK-NEXT: {{ $}}
53+
; CHECK-NEXT: bb.6:
54+
; CHECK-NEXT: successors: %bb.11(0x80000000)
55+
; CHECK-NEXT: {{ $}}
56+
; CHECK-NEXT: [[COPY6:%[0-9]+]]:gpr = COPY $r0
57+
; CHECK-NEXT: PseudoBR %bb.11
58+
; CHECK-NEXT: {{ $}}
59+
; CHECK-NEXT: bb.7:
60+
; CHECK-NEXT: successors: %bb.8(0x7c000000), %bb.10(0x04000000)
61+
; CHECK-NEXT: {{ $}}
62+
; CHECK-NEXT: BEQZ [[ANDI2]], %bb.10
63+
; CHECK-NEXT: PseudoBR %bb.8
64+
; CHECK-NEXT: {{ $}}
65+
; CHECK-NEXT: bb.8:
66+
; CHECK-NEXT: successors: %bb.9(0x04000000), %bb.5(0x7c000000)
67+
; CHECK-NEXT: {{ $}}
68+
; CHECK-NEXT: [[COPY6:%[0-9]+]]:gpr = ADDI_D [[COPY6]], 1
69+
; CHECK-NEXT: BEQZ [[ANDI3]], %bb.5
70+
; CHECK-NEXT: PseudoBR %bb.9
71+
; CHECK-NEXT: {{ $}}
72+
; CHECK-NEXT: bb.9:
73+
; CHECK-NEXT: successors: %bb.12(0x80000000)
74+
; CHECK-NEXT: {{ $}}
75+
; CHECK-NEXT: ST_B $r0, [[COPY4]], 0
76+
; CHECK-NEXT: PseudoBR %bb.12
77+
; CHECK-NEXT: {{ $}}
78+
; CHECK-NEXT: bb.10:
79+
; CHECK-NEXT: successors: %bb.11(0x80000000)
80+
; CHECK-NEXT: {{ $}}
81+
; CHECK-NEXT: [[COPY5:%[0-9]+]]:gpr = ADDI_D [[COPY6]], 1
82+
; CHECK-NEXT: [[COPY6:%[0-9]+]]:gpr = COPY [[ORI]]
83+
; CHECK-NEXT: {{ $}}
84+
; CHECK-NEXT: bb.11:
85+
; CHECK-NEXT: successors: %bb.12(0x80000000)
86+
; CHECK-NEXT: {{ $}}
87+
; CHECK-NEXT: ST_D $r0, [[COPY4]], 0
88+
; CHECK-NEXT: {{ $}}
89+
; CHECK-NEXT: bb.12:
90+
; CHECK-NEXT: successors: %bb.2(0x7c000000), %bb.1(0x04000000)
91+
; CHECK-NEXT: {{ $}}
92+
; CHECK-NEXT: BEQ [[COPY7]], [[ORI]], %bb.2
93+
; CHECK-NEXT: PseudoBR %bb.1
94+
bb.0:
95+
liveins: $r4, $r5, $r6, $r7, $r8
96+
97+
%0:gpr = COPY killed $r8
98+
%1:gpr = COPY killed $r7
99+
%2:gpr = COPY killed $r6
100+
%3:gpr = COPY killed $r5
101+
%4:gpr = COPY killed $r4
102+
%5:gpr = COPY $r0
103+
%6:gpr = COPY killed %5
104+
%7:gpr = ANDI killed %3, 1
105+
%8:gpr = ORI $r0, 1
106+
%9:gpr = ANDI killed %2, 1
107+
%10:gpr = ANDI killed %1, 1
108+
%11:gpr = ANDI killed %0, 1
109+
%12:gpr = COPY %6
110+
%13:gpr = COPY killed %6
111+
%14:gpr = IMPLICIT_DEF
112+
113+
bb.1:
114+
%15:gpr = COPY killed %14
115+
%16:gpr = COPY killed %13
116+
%17:gpr = COPY killed %12
117+
%18:gpr = COPY %17
118+
%19:gpr = COPY %16
119+
%20:gpr = COPY killed %16
120+
%21:gpr = COPY killed %15
121+
122+
bb.2:
123+
successors: %bb.3, %bb.4
124+
125+
%22:gpr = COPY killed %21
126+
%23:gpr = COPY killed %20
127+
%24:gpr = COPY killed %19
128+
%25:gpr = COPY killed %18
129+
BEQZ %7, %bb.4
130+
131+
bb.3:
132+
%26:gpr = COPY killed %24
133+
%27:gpr = COPY killed %23
134+
PseudoBR %bb.9
135+
136+
bb.4:
137+
%28:gpr = COPY killed %23
138+
139+
bb.5:
140+
successors: %bb.7(0x7c000000), %bb.6(0x04000000)
141+
142+
%29:gpr = COPY killed %28
143+
dead %30:gpr = LD_D $r0, 8
144+
dead %31:gpr = LD_D $r0, 0
145+
BNEZ %9, %bb.7
146+
147+
bb.6:
148+
%32:gpr = COPY $r0
149+
%33:gpr = COPY killed %32
150+
%34:gpr = COPY killed %33
151+
%35:gpr = COPY killed %22
152+
PseudoBR %bb.11
153+
154+
bb.7:
155+
successors: %bb.8(0x7c000000), %bb.10(0x04000000)
156+
157+
BEQZ %10, %bb.10
158+
PseudoBR %bb.8
159+
160+
bb.8:
161+
successors: %bb.9(0x04000000), %bb.5(0x7c000000)
162+
163+
%36:gpr = ADDI_D killed %29, 1
164+
%28:gpr = COPY %36
165+
%26:gpr = COPY %36
166+
%27:gpr = COPY killed %36
167+
BEQZ %11, %bb.5
168+
PseudoBR %bb.9
169+
170+
bb.9:
171+
%37:gpr = COPY killed %27
172+
%38:gpr = COPY killed %26
173+
%39:gpr = COPY $r0
174+
ST_B killed %39, %4, 0
175+
%40:gpr = COPY killed %25
176+
%41:gpr = COPY killed %38
177+
%42:gpr = COPY killed %37
178+
%43:gpr = COPY killed %22
179+
PseudoBR %bb.12
180+
181+
bb.10:
182+
%44:gpr = ADDI_D killed %29, 1
183+
%34:gpr = COPY %8
184+
%35:gpr = COPY killed %44
185+
186+
bb.11:
187+
%45:gpr = COPY killed %35
188+
%46:gpr = COPY killed %34
189+
%47:gpr = COPY $r0
190+
ST_D killed %47, %4, 0
191+
%40:gpr = COPY %45
192+
%41:gpr = COPY %46
193+
%42:gpr = COPY killed %46
194+
%43:gpr = COPY killed %45
195+
196+
bb.12:
197+
successors: %bb.2(0x7c000000), %bb.1(0x04000000)
198+
199+
%48:gpr = COPY killed %43
200+
%49:gpr = COPY killed %42
201+
%50:gpr = COPY killed %41
202+
%51:gpr = COPY killed %40
203+
%12:gpr = COPY %51
204+
%13:gpr = COPY %50
205+
%14:gpr = COPY %48
206+
%18:gpr = COPY killed %51
207+
%19:gpr = COPY killed %50
208+
%20:gpr = COPY killed %49
209+
%21:gpr = COPY killed %48
210+
BEQ %17, %8, %bb.2
211+
PseudoBR %bb.1
212+
213+
...
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2+
; RUN: llc < %s -mtriple=x86_64 -- | FileCheck %s
3+
4+
define i32 @h(i1 %arg, i32 %arg1) {
5+
; CHECK-LABEL: h:
6+
; CHECK: # %bb.0: # %bb
7+
; CHECK-NEXT: movl $1, %eax
8+
; CHECK-NEXT: movabsq $9166129423, %rcx # imm = 0x22258090F
9+
; CHECK-NEXT: xorl %edx, %edx
10+
; CHECK-NEXT: jmp .LBB0_1
11+
; CHECK-NEXT: .p2align 4, 0x90
12+
; CHECK-NEXT: .LBB0_9: # %bb18
13+
; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
14+
; CHECK-NEXT: xorl %eax, %eax
15+
; CHECK-NEXT: testb $1, %dil
16+
; CHECK-NEXT: jne .LBB0_10
17+
; CHECK-NEXT: .LBB0_1: # %bb4
18+
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
19+
; CHECK-NEXT: testq %rdx, %rdx
20+
; CHECK-NEXT: jne .LBB0_2
21+
; CHECK-NEXT: # %bb.7: # %bb16
22+
; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
23+
; CHECK-NEXT: testb $1, %dil
24+
; CHECK-NEXT: jne .LBB0_9
25+
; CHECK-NEXT: # %bb.8: # %bb17
26+
; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
27+
; CHECK-NEXT: movq %rcx, %rdx
28+
; CHECK-NEXT: jmp .LBB0_9
29+
; CHECK-NEXT: .LBB0_2: # %bb9
30+
; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
31+
; CHECK-NEXT: testb $1, %dil
32+
; CHECK-NEXT: testb $1, %dil
33+
; CHECK-NEXT: je .LBB0_4
34+
; CHECK-NEXT: # %bb.3: # %bb13
35+
; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
36+
; CHECK-NEXT: xorl %eax, %eax
37+
; CHECK-NEXT: .LBB0_4: # %bb14
38+
; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=1
39+
; CHECK-NEXT: cmpl $1, %esi
40+
; CHECK-NEXT: je .LBB0_1
41+
; CHECK-NEXT: # %bb.5: # %bb14
42+
; CHECK-NEXT: movl %eax, %r8d
43+
; CHECK-NEXT: testl %esi, %esi
44+
; CHECK-NEXT: movl %esi, %eax
45+
; CHECK-NEXT: jne .LBB0_6
46+
; CHECK-NEXT: .LBB0_10: # %bb22
47+
; CHECK-NEXT: retq
48+
; CHECK-NEXT: .LBB0_6: # %bb22.loopexit1
49+
; CHECK-NEXT: movl %r8d, %eax
50+
; CHECK-NEXT: retq
51+
bb:
52+
br label %bb2
53+
54+
bb2: ; preds = %bb14, %bb
55+
%i = phi i64 [ %i5, %bb14 ], [ 0, %bb ]
56+
%i3 = phi i32 [ %i15, %bb14 ], [ 1, %bb ]
57+
br label %bb4
58+
59+
bb4: ; preds = %bb18, %bb2
60+
%i5 = phi i64 [ %i19, %bb18 ], [ %i, %bb2 ]
61+
%i6 = phi i64 [ %i20, %bb18 ], [ %i, %bb2 ]
62+
%i7 = phi i32 [ 0, %bb18 ], [ %i3, %bb2 ]
63+
%i8 = icmp eq i64 %i6, 0
64+
br i1 %i8, label %bb16, label %bb9
65+
66+
bb9: ; preds = %bb4
67+
br i1 %arg, label %bb12, label %bb10
68+
69+
bb10: ; preds = %bb9
70+
%i11 = sdiv i64 0, 0
71+
br label %bb12
72+
73+
bb12: ; preds = %bb10, %bb9
74+
br i1 %arg, label %bb13, label %bb14
75+
76+
bb13: ; preds = %bb12
77+
br label %bb14
78+
79+
bb14: ; preds = %bb13, %bb12
80+
%i15 = phi i32 [ 0, %bb13 ], [ %i7, %bb12 ]
81+
switch i32 %arg1, label %bb22 [
82+
i32 0, label %bb21
83+
i32 1, label %bb2
84+
]
85+
86+
bb16: ; preds = %bb4
87+
br i1 %arg, label %bb18, label %bb17
88+
89+
bb17: ; preds = %bb16
90+
br label %bb18
91+
92+
bb18: ; preds = %bb17, %bb16
93+
%i19 = phi i64 [ 9166129423, %bb17 ], [ %i5, %bb16 ]
94+
%i20 = phi i64 [ 9166129423, %bb17 ], [ %i6, %bb16 ]
95+
br i1 %arg, label %bb22, label %bb4
96+
97+
bb21: ; preds = %bb14
98+
br label %bb22
99+
100+
bb22: ; preds = %bb21, %bb18, %bb14
101+
%i23 = phi i32 [ %arg1, %bb21 ], [ %i15, %bb14 ], [ 0, %bb18 ]
102+
ret i32 %i23
103+
}

0 commit comments

Comments
 (0)