Skip to content

Commit 4a21e3a

Browse files
authored
[LiveIntervals] repairIntervalsInRange: recompute width changes (#78564)
Extend repairIntervalsInRange to completely recompute the interva for a register if subregister defs exist without precise subrange matches (LaneMask exactly matching subregister). This occurs when register sequences are lowered to copies such that the size of the copies do not match any uses of the subregisters formed (i.e. during twoaddressinstruction). The subranges without this change are probably legal, but do not match those generated by live interval computation. This creates problems with other code that assumes subranges precisely cover all subregisters defined, e.g. shrinkToUses().
1 parent f645560 commit 4a21e3a

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

llvm/lib/CodeGen/LiveIntervals.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,13 +1666,27 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
16661666
for (const MachineOperand &MO : MI.operands()) {
16671667
if (MO.isReg() && MO.getReg().isVirtual()) {
16681668
Register Reg = MO.getReg();
1669-
// If the new instructions refer to subregs but the old instructions did
1670-
// not, throw away any old live interval so it will be recomputed with
1671-
// subranges.
16721669
if (MO.getSubReg() && hasInterval(Reg) &&
1673-
!getInterval(Reg).hasSubRanges() &&
1674-
MRI->shouldTrackSubRegLiveness(Reg))
1675-
removeInterval(Reg);
1670+
MRI->shouldTrackSubRegLiveness(Reg)) {
1671+
LiveInterval &LI = getInterval(Reg);
1672+
if (!LI.hasSubRanges()) {
1673+
// If the new instructions refer to subregs but the old instructions
1674+
// did not, throw away any old live interval so it will be
1675+
// recomputed with subranges.
1676+
removeInterval(Reg);
1677+
} else if (MO.isDef()) {
1678+
// Similarly if a subreg def has no precise subrange match then
1679+
// assume we need to recompute all subranges.
1680+
unsigned SubReg = MO.getSubReg();
1681+
LaneBitmask Mask = TRI->getSubRegIndexLaneMask(SubReg);
1682+
if (llvm::none_of(LI.subranges(),
1683+
[Mask](LiveInterval::SubRange &SR) {
1684+
return SR.LaneMask == Mask;
1685+
})) {
1686+
removeInterval(Reg);
1687+
}
1688+
}
1689+
}
16761690
if (!hasInterval(Reg)) {
16771691
createAndComputeVirtRegInterval(Reg);
16781692
// Don't bother to repair a freshly calculated live interval.

llvm/test/CodeGen/AMDGPU/lds-misaligned-bug.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
; RUN: llc -mtriple=amdgcn -mcpu=gfx1010 -verify-machineinstrs -mattr=+cumode,+unaligned-access-mode < %s | FileCheck -check-prefixes=GCN,UNALIGNED,VECT %s
66
; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs < %s | FileCheck -check-prefixes=GCN,ALIGNED,VECT %s
77
; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs -mattr=+cumode < %s | FileCheck -check-prefixes=GCN,ALIGNED,VECT %s
8+
; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs -mattr=+cumode -early-live-intervals < %s | FileCheck -check-prefixes=GCN,ALIGNED,VECT %s
89
; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs -mattr=+cumode,+unaligned-access-mode < %s | FileCheck -check-prefixes=GCN,UNALIGNED,VECT %s
910

1011
; GCN-LABEL: test_local_misaligned_v2:

0 commit comments

Comments
 (0)