Skip to content

Commit d00b0aa

Browse files
committed
RegisterCoalescer: Fix verifier error when merging copy of undef
There's no real read of the register, so the copy introduced a new live value. Make sure we introduce a replacement implicit_def instead of just erasing the copy. Found from llvm-reduce since it tries to set undef on everything.
1 parent 4fdda4f commit d00b0aa

File tree

3 files changed

+76
-12
lines changed

3 files changed

+76
-12
lines changed

llvm/lib/CodeGen/RegisterCoalescer.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,18 +1641,20 @@ MachineInstr *RegisterCoalescer::eliminateUndefCopy(MachineInstr *CopyMI) {
16411641
SlotIndex RegIndex = Idx.getRegSlot();
16421642
LiveRange::Segment *Seg = DstLI.getSegmentContaining(RegIndex);
16431643
assert(Seg != nullptr && "No segment for defining instruction");
1644-
if (VNInfo *V = DstLI.getVNInfoAt(Seg->end)) {
1645-
if (V->isPHIDef()) {
1646-
CopyMI->setDesc(TII->get(TargetOpcode::IMPLICIT_DEF));
1647-
for (unsigned i = CopyMI->getNumOperands(); i != 0; --i) {
1648-
MachineOperand &MO = CopyMI->getOperand(i-1);
1649-
if (MO.isReg() && MO.isUse())
1650-
CopyMI->removeOperand(i-1);
1651-
}
1652-
LLVM_DEBUG(dbgs() << "\tReplaced copy of <undef> value with an "
1653-
"implicit def\n");
1654-
return CopyMI;
1644+
VNInfo *V = DstLI.getVNInfoAt(Seg->end);
1645+
1646+
// The source interval may also have been on an undef use, in which case the
1647+
// copy introduced a live value.
1648+
if (((V && V->isPHIDef()) || (!V && !DstLI.liveAt(Idx)))) {
1649+
CopyMI->setDesc(TII->get(TargetOpcode::IMPLICIT_DEF));
1650+
for (unsigned i = CopyMI->getNumOperands(); i != 0; --i) {
1651+
MachineOperand &MO = CopyMI->getOperand(i-1);
1652+
if (MO.isReg() && MO.isUse())
1653+
CopyMI->removeOperand(i-1);
16551654
}
1655+
LLVM_DEBUG(dbgs() << "\tReplaced copy of <undef> value with an "
1656+
"implicit def\n");
1657+
return CopyMI;
16561658
}
16571659

16581660
// Remove any DstReg segments starting at the instruction.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -verify-coalescing -run-pass=simple-register-coalescing -o - %s | FileCheck %s
3+
4+
# %2 has an undef read in %bb.3, and this IR wouldn't be valid if it
5+
# was a real read. After merging %2 into %0, we need to replace the
6+
# copy of undef with an implicit_def since the copy introduced a new
7+
# value.
8+
9+
---
10+
name: coalesce_into_undef_copy
11+
tracksRegLiveness: true
12+
machineFunctionInfo:
13+
scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3'
14+
stackPtrOffsetReg: '$sgpr32'
15+
body: |
16+
; CHECK-LABEL: name: coalesce_into_undef_copy
17+
; CHECK: bb.0:
18+
; CHECK-NEXT: successors: %bb.1(0x80000000)
19+
; CHECK-NEXT: {{ $}}
20+
; CHECK-NEXT: [[COPY:%[0-9]+]]:vreg_128_align2 = COPY undef %1:sgpr_128, implicit $exec
21+
; CHECK-NEXT: S_BRANCH %bb.1
22+
; CHECK-NEXT: {{ $}}
23+
; CHECK-NEXT: bb.1:
24+
; CHECK-NEXT: successors: %bb.2(0x80000000)
25+
; CHECK-NEXT: {{ $}}
26+
; CHECK-NEXT: dead %2:vreg_128_align2 = IMPLICIT_DEF
27+
; CHECK-NEXT: [[COPY]].sub0:vreg_128_align2 = IMPLICIT_DEF
28+
; CHECK-NEXT: {{ $}}
29+
; CHECK-NEXT: bb.2:
30+
; CHECK-NEXT: successors: %bb.2(0x80000000)
31+
; CHECK-NEXT: {{ $}}
32+
; CHECK-NEXT: dead %4:vgpr_32 = V_INDIRECT_REG_READ_GPR_IDX_B32_V4 [[COPY]], undef %5:sgpr_32, 11, implicit-def $m0, implicit $m0, implicit $exec
33+
; CHECK-NEXT: S_BRANCH %bb.2
34+
; CHECK-NEXT: {{ $}}
35+
; CHECK-NEXT: bb.3:
36+
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.4(0x40000000)
37+
; CHECK-NEXT: {{ $}}
38+
; CHECK-NEXT: [[DEF:%[0-9]+]]:vreg_128_align2 = IMPLICIT_DEF
39+
; CHECK-NEXT: S_CBRANCH_EXECNZ %bb.1, implicit $exec
40+
; CHECK-NEXT: {{ $}}
41+
; CHECK-NEXT: bb.4:
42+
bb.0:
43+
%0:vreg_128_align2 = COPY undef %1:sgpr_128, implicit $exec
44+
S_BRANCH %bb.1
45+
46+
bb.1:
47+
%2:vreg_128_align2 = IMPLICIT_DEF
48+
%3:vreg_128_align2 = COPY killed %0
49+
%3.sub0:vreg_128_align2 = IMPLICIT_DEF
50+
51+
bb.2:
52+
dead %5:vgpr_32 = V_INDIRECT_REG_READ_GPR_IDX_B32_V4 %3, undef %6:sgpr_32, 11, implicit-def $m0, implicit $m0, implicit $exec
53+
S_BRANCH %bb.2
54+
55+
bb.3:
56+
%0:vreg_128_align2 = COPY undef %2
57+
S_CBRANCH_EXECNZ %bb.1, implicit $exec
58+
59+
bb.4:
60+
61+
...

llvm/test/CodeGen/AMDGPU/undef-subreg-use-after-coalesce.mir

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ body: |
3232
; CHECK-LABEL: name: undef_subreg_use_after_full_copy_coalesce_composed
3333
; CHECK: undef %0.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec
3434
; CHECK-NEXT: dead %0.sub1:vreg_128 = V_MOV_B32_e32 0, implicit $exec
35-
; CHECK-NEXT: S_ENDPGM 0, implicit undef %2.sub1:vreg_64
35+
; CHECK-NEXT: [[DEF:%[0-9]+]]:vreg_64 = IMPLICIT_DEF
36+
; CHECK-NEXT: S_ENDPGM 0, implicit [[DEF]].sub1
3637
undef %0.sub0:vreg_128 = V_MOV_B32_e32 0, implicit $exec
3738
%0.sub1:vreg_128 = V_MOV_B32_e32 0, implicit $exec
3839
%1:vreg_128 = COPY killed %0

0 commit comments

Comments
 (0)