Skip to content

Commit ba382b7

Browse files
[TEMP] Fix LiveRegMatrix dangling pointers in postOptimization
1 parent c1606b3 commit ba382b7

File tree

3 files changed

+40
-3
lines changed

3 files changed

+40
-3
lines changed

llvm/include/llvm/CodeGen/LiveRangeEdit.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/ADT/ArrayRef.h"
2121
#include "llvm/ADT/SetVector.h"
2222
#include "llvm/ADT/SmallPtrSet.h"
23+
#include "llvm/ADT/SmallSet.h"
2324
#include "llvm/ADT/SmallVector.h"
2425
#include "llvm/CodeGen/LiveInterval.h"
2526
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -58,6 +59,11 @@ class LiveRangeEdit : private MachineRegisterInfo::Delegate {
5859
/// Called before shrinking the live range of a virtual register.
5960
virtual void LRE_WillShrinkVirtReg(Register) {}
6061

62+
/// Called when a virtual register's LiveInterval is about to become empty.
63+
/// This happens when removeVRegDefAt removes the last definition.
64+
/// Implementations should unassign from LiveRegMatrix before the interval is cleared.
65+
virtual void LRE_WillClearVirtReg(Register, LiveInterval &) {}
66+
6167
/// Called after cloning a virtual register.
6268
/// This is used for new registers representing connected components of Old.
6369
virtual void LRE_DidCloneVirtReg(Register New, Register Old) {}
@@ -75,6 +81,11 @@ class LiveRangeEdit : private MachineRegisterInfo::Delegate {
7581
/// FirstNew - Index of the first register added to NewRegs.
7682
const unsigned FirstNew;
7783

84+
/// Track which virtual registers are new (created during this edit).
85+
/// Used to avoid calling Matrix->unassign on registers that were never
86+
/// added to LiveRegMatrix.
87+
SmallSet<Register, 8> NewVirtRegs;
88+
7889
/// DeadRemats - The saved instructions which have already been dead after
7990
/// rematerialization but not deleted yet -- to be done in postOptimization.
8091
SmallPtrSet<MachineInstr *, 32> *DeadRemats;
@@ -142,6 +153,12 @@ class LiveRangeEdit : private MachineRegisterInfo::Delegate {
142153
bool empty() const { return size() == 0; }
143154
Register get(unsigned idx) const { return NewRegs[idx + FirstNew]; }
144155

156+
/// Check if a virtual register was created during this edit.
157+
/// This is used to identify registers that were never added to LiveRegMatrix.
158+
bool isNewVirtualRegister(Register VReg) const {
159+
return NewVirtRegs.contains(VReg);
160+
}
161+
145162
/// pop_back - It allows LiveRangeEdit users to drop new registers.
146163
/// The context is when an original def instruction of a register is
147164
/// dead after rematerialization, we still want to keep it for following

llvm/lib/CodeGen/InlineSpiller.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class HoistSpillHelper : private LiveRangeEdit::Delegate {
8686
const TargetInstrInfo &TII;
8787
const TargetRegisterInfo &TRI;
8888
const MachineBlockFrequencyInfo &MBFI;
89+
LiveRegMatrix *Matrix;
8990

9091
InsertPointAnalysis IPA;
9192

@@ -129,16 +130,18 @@ class HoistSpillHelper : private LiveRangeEdit::Delegate {
129130

130131
public:
131132
HoistSpillHelper(const Spiller::RequiredAnalyses &Analyses,
132-
MachineFunction &mf, VirtRegMap &vrm)
133+
MachineFunction &mf, VirtRegMap &vrm,
134+
LiveRegMatrix *matrix = nullptr)
133135
: MF(mf), LIS(Analyses.LIS), LSS(Analyses.LSS), MDT(Analyses.MDT),
134136
VRM(vrm), MRI(mf.getRegInfo()), TII(*mf.getSubtarget().getInstrInfo()),
135137
TRI(*mf.getSubtarget().getRegisterInfo()), MBFI(Analyses.MBFI),
136-
IPA(LIS, mf.getNumBlockIDs()) {}
138+
Matrix(matrix), IPA(LIS, mf.getNumBlockIDs()) {}
137139

138140
void addToMergeableSpills(MachineInstr &Spill, int StackSlot,
139141
Register Original);
140142
bool rmFromMergeableSpills(MachineInstr &Spill, int StackSlot);
141143
void hoistAllSpills();
144+
void LRE_WillClearVirtReg(Register, LiveInterval &) override;
142145
void LRE_DidCloneVirtReg(Register, Register) override;
143146
};
144147

@@ -191,7 +194,7 @@ class InlineSpiller : public Spiller {
191194
: MF(MF), LIS(Analyses.LIS), LSS(Analyses.LSS), VRM(VRM),
192195
MRI(MF.getRegInfo()), TII(*MF.getSubtarget().getInstrInfo()),
193196
TRI(*MF.getSubtarget().getRegisterInfo()), Matrix(Matrix),
194-
HSpiller(Analyses, MF, VRM), VRAI(VRAI) {}
197+
HSpiller(Analyses, MF, VRM, Matrix), VRAI(VRAI) {}
195198

196199
void spill(LiveRangeEdit &, AllocationOrder *Order = nullptr) override;
197200
ArrayRef<Register> getSpilledRegs() override { return RegsToSpill; }
@@ -1750,6 +1753,17 @@ void HoistSpillHelper::hoistAllSpills() {
17501753
}
17511754
}
17521755

1756+
/// Called when a LiveInterval is about to be cleared by removeVRegDefAt.
1757+
/// Unassign from LiveRegMatrix to prevent dangling pointers (fixes LLVM bug #48911).
1758+
void HoistSpillHelper::LRE_WillClearVirtReg(Register VirtReg,
1759+
LiveInterval &LI) {
1760+
// If this virtual register is assigned to a physical register, unassign it
1761+
// from LiveRegMatrix before the interval is cleared. Otherwise, LiveIntervalUnion
1762+
// will contain dangling pointers.
1763+
if (Matrix && VRM.hasPhys(VirtReg))
1764+
Matrix->unassign(LI);
1765+
}
1766+
17531767
/// For VirtReg clone, the \p New register should have the same physreg or
17541768
/// stackslot as the \p old register.
17551769
void HoistSpillHelper::LRE_DidCloneVirtReg(Register New, Register Old) {

llvm/lib/CodeGen/LiveRangeEdit.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,11 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {
268268
if (MO.isDef()) {
269269
if (TheDelegate && LI.getVNInfoAt(Idx) != nullptr)
270270
TheDelegate->LRE_WillShrinkVirtReg(LI.reg());
271+
// Notify delegate BEFORE clearing if this will make the interval empty.
272+
// This allows Matrix->unassign to work with non-empty LiveRange.
273+
// Skip new registers (clones) - they were never added to LiveRegMatrix.
274+
if (TheDelegate && LI.size() == 1 && !isNewVirtualRegister(Reg))
275+
TheDelegate->LRE_WillClearVirtReg(Reg, LI);
271276
LIS.removeVRegDefAt(LI, Idx);
272277
if (LI.empty())
273278
RegsToErase.push_back(Reg);
@@ -398,6 +403,7 @@ LiveRangeEdit::MRI_NoteNewVirtualRegister(Register VReg) {
398403
VRM->grow();
399404

400405
NewRegs.push_back(VReg);
406+
NewVirtRegs.insert(VReg);
401407
}
402408

403409
void LiveRangeEdit::calculateRegClassAndHint(MachineFunction &MF,

0 commit comments

Comments
 (0)