Skip to content

Commit 538a83e

Browse files
authored
RegisterCoalescer: Add undef flags in removePartialRedundancy (#75152)
If the copy being hoisted was undef, we have the same problems that eliminateUndefCopy needs to solve. We would effectively be introducing a new live out implicit_def. We need to add an undef flag to avoid artificially introducing a live through undef value. Previously, the verifier would fail due to the dead def inside the loop providing the live in value for the %1 use.
1 parent aee93cf commit 538a83e

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

llvm/lib/CodeGen/RegisterCoalescer.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,8 @@ bool RegisterCoalescer::removePartialRedundancy(const CoalescerPair &CP,
12011201
<< printMBBReference(MBB) << '\t' << CopyMI);
12021202
}
12031203

1204+
const bool IsUndefCopy = CopyMI.getOperand(1).isUndef();
1205+
12041206
// Remove CopyMI.
12051207
// Note: This is fine to remove the copy before updating the live-ranges.
12061208
// While updating the live-ranges, we only look at slot indices and
@@ -1214,6 +1216,19 @@ bool RegisterCoalescer::removePartialRedundancy(const CoalescerPair &CP,
12141216
LIS->pruneValue(*static_cast<LiveRange *>(&IntB), CopyIdx.getRegSlot(),
12151217
&EndPoints);
12161218
BValNo->markUnused();
1219+
1220+
if (IsUndefCopy) {
1221+
// We're introducing an undef phi def, and need to set undef on any users of
1222+
// the previously local def to avoid artifically extending the lifetime
1223+
// through the block.
1224+
for (MachineOperand &MO : MRI->use_nodbg_operands(IntB.reg())) {
1225+
const MachineInstr &MI = *MO.getParent();
1226+
SlotIndex UseIdx = LIS->getInstructionIndex(MI);
1227+
if (!IntB.liveAt(UseIdx))
1228+
MO.setIsUndef(true);
1229+
}
1230+
}
1231+
12171232
// Extend IntB to the EndPoints of its original live interval.
12181233
LIS->extendToIndices(IntB, EndPoints);
12191234

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
2+
# RUN: llc -mtriple=x86_64-pc-linux-gnu -run-pass=register-coalescer -verify-coalescing -o - %s | FileCheck %s
3+
4+
# Check for "Live range continues after dead def flag".
5+
6+
# There are 2 copies of undef, but the registers also appear to be
7+
# live due to block live outs, and thus were not deleted as
8+
# eliminateUndefCopy only considered the live range, and not the undef
9+
# flag.
10+
#
11+
# removePartialRedundancy would move the COPY undef %0 in bb.1 to
12+
# bb.0. The live range of %1 would then be extended to be live out of
13+
# %bb.1 for the backedge phi. This would then fail the verifier, since
14+
# the dead flag was no longer valid. This was fixed by directly
15+
# considering the undef flag to avoid considering this special case.
16+
17+
---
18+
name: partial_redundancy_coalesce_undef_copy_live_out
19+
tracksRegLiveness: true
20+
body: |
21+
; CHECK-LABEL: name: partial_redundancy_coalesce_undef_copy_live_out
22+
; CHECK: bb.0:
23+
; CHECK-NEXT: successors: %bb.1(0x80000000)
24+
; CHECK-NEXT: liveins: $rdi
25+
; CHECK-NEXT: {{ $}}
26+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $rdi
27+
; CHECK-NEXT: {{ $}}
28+
; CHECK-NEXT: bb.1:
29+
; CHECK-NEXT: successors: %bb.1(0x80000000)
30+
; CHECK-NEXT: {{ $}}
31+
; CHECK-NEXT: dead [[XOR32ri:%[0-9]+]]:gr32 = XOR32ri undef [[XOR32ri]], 1, implicit-def dead $eflags
32+
; CHECK-NEXT: dead [[MOV32rr:%[0-9]+]]:gr32 = MOV32rr [[COPY]]
33+
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = IMPLICIT_DEF
34+
; CHECK-NEXT: JMP_1 %bb.1
35+
bb.0:
36+
liveins: $rdi
37+
38+
%0:gr32 = COPY $rdi
39+
40+
bb.1:
41+
%1:gr32 = COPY undef %0
42+
dead %1:gr32 = XOR32ri %1, 1, implicit-def dead $eflags
43+
dead %2:gr32 = MOV32rr killed %0
44+
%0:gr32 = COPY killed undef %1
45+
JMP_1 %bb.1
46+
47+
...

0 commit comments

Comments
 (0)