Skip to content

Commit 40abb28

Browse files
committed
RegAllocGreedy: Fix subranges when rematerializing dead subreg defs
This would create a new interval missing the subrange and hit this verifier error: *** Bad machine code: Live interval for subreg operand has no subranges *** - function: test_remat_subreg_def - basic block: %bb.0 (0xa568758) [0B;128B) - instruction: 32B dead undef %4.sub0:vreg_64 = V_MOV_B32_e32 2, implicit $exec
1 parent 162ec61 commit 40abb28

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

llvm/lib/CodeGen/LiveRangeEdit.cpp

+14-2
Original file line numberDiff line numberDiff line change
@@ -300,13 +300,15 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {
300300
SmallVector<unsigned, 8> RegsToErase;
301301
bool ReadsPhysRegs = false;
302302
bool isOrigDef = false;
303-
unsigned Dest;
303+
Register Dest;
304+
unsigned DestSubReg;
304305
// Only optimize rematerialize case when the instruction has one def, since
305306
// otherwise we could leave some dead defs in the code. This case is
306307
// extremely rare.
307308
if (VRM && MI->getOperand(0).isReg() && MI->getOperand(0).isDef() &&
308309
MI->getDesc().getNumDefs() == 1) {
309310
Dest = MI->getOperand(0).getReg();
311+
DestSubReg = MI->getOperand(0).getSubReg();
310312
unsigned Original = VRM->getOriginal(Dest);
311313
LiveInterval &OrigLI = LIS.getInterval(Original);
312314
VNInfo *OrigVNI = OrigLI.getVNInfoAt(Idx);
@@ -384,8 +386,18 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {
384386
if (isOrigDef && DeadRemats && !HasLiveVRegUses &&
385387
TII.isTriviallyReMaterializable(*MI)) {
386388
LiveInterval &NewLI = createEmptyIntervalFrom(Dest, false);
387-
VNInfo *VNI = NewLI.getNextValue(Idx, LIS.getVNInfoAllocator());
389+
VNInfo::Allocator &Alloc = LIS.getVNInfoAllocator();
390+
VNInfo *VNI = NewLI.getNextValue(Idx, Alloc);
388391
NewLI.addSegment(LiveInterval::Segment(Idx, Idx.getDeadSlot(), VNI));
392+
393+
if (DestSubReg) {
394+
const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
395+
auto *SR = NewLI.createSubRange(
396+
Alloc, TRI->getSubRegIndexLaneMask(DestSubReg));
397+
SR->addSegment(LiveInterval::Segment(Idx, Idx.getDeadSlot(),
398+
SR->getNextValue(Idx, Alloc)));
399+
}
400+
389401
pop_back();
390402
DeadRemats->insert(MI);
391403
const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();

llvm/test/CodeGen/AMDGPU/remat-vop.mir

+26-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2-
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -verify-machineinstrs --stress-regalloc=2 -start-before=greedy,0 -stop-after=virtregrewriter,1 -o - %s | FileCheck -check-prefix=GCN %s
2+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx90a -verify-regalloc --stress-regalloc=2 -start-before=greedy,0 -stop-after=virtregrewriter,1 -o - %s | FileCheck -check-prefix=GCN %s
33

44
---
55
name: test_remat_v_mov_b32_e32
@@ -5385,3 +5385,28 @@ body: |
53855385
S_NOP 0, implicit %3
53865386
S_ENDPGM 0, implicit %0
53875387
...
5388+
5389+
# Make sure there's no verifier error after making a subregister def dead. The
5390+
# dead interval still needs a subrange.
5391+
5392+
---
5393+
name: test_remat_subreg_def
5394+
tracksRegLiveness: true
5395+
body: |
5396+
bb.0:
5397+
; GCN-LABEL: name: test_remat_subreg_def
5398+
; GCN: renamable $vgpr1 = V_MOV_B32_e32 1, implicit $exec
5399+
; GCN-NEXT: renamable $vgpr0 = V_MOV_B32_e32 3, implicit $exec
5400+
; GCN-NEXT: S_NOP 0, implicit killed renamable $vgpr1
5401+
; GCN-NEXT: S_NOP 0, implicit killed renamable $vgpr0
5402+
; GCN-NEXT: renamable $vgpr0 = V_MOV_B32_e32 2, implicit $exec
5403+
; GCN-NEXT: S_NOP 0, implicit renamable $vgpr0_vgpr1
5404+
; GCN-NEXT: S_ENDPGM 0
5405+
%0:vgpr_32 = V_MOV_B32_e32 1, implicit $exec
5406+
undef %1.sub0:vreg_64 = V_MOV_B32_e32 2, implicit $exec
5407+
%2:vgpr_32 = V_MOV_B32_e32 3, implicit $exec
5408+
S_NOP 0, implicit %0
5409+
S_NOP 0, implicit %2
5410+
S_NOP 0, implicit %1
5411+
S_ENDPGM 0
5412+
...

0 commit comments

Comments
 (0)