Skip to content

Commit 5cb8212

Browse files
committed
[regalloc] Add validity check for LiveRegMatrix to prevent dangling pointers
- Implemented `isValid()` method in LiveRegMatrix to verify that all LiveInterval pointers are valid. - Added assertion in RegAllocBase's `postOptimization()` to ensure no dangling pointers exist in LiveRegMatrix after spilling.
1 parent e9f74df commit 5cb8212

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

llvm/include/llvm/CodeGen/LiveRegMatrix.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,16 @@ class LiveRegMatrix {
170170
}
171171

172172
Register getOneVReg(unsigned PhysReg) const;
173+
174+
/// Verify that all LiveInterval pointers in the matrix are valid.
175+
/// This checks that each LiveInterval referenced in LiveIntervalUnion
176+
/// actually exists in LiveIntervals and is not a dangling pointer.
177+
/// Returns true if the matrix is valid, false if dangling pointers are found.
178+
/// This is primarily useful for debugging heap-use-after-free issues.
179+
/// This method uses a lazy approach - it builds a set of valid LiveInterval
180+
/// pointers on-demand and has zero runtime/memory overhead during normal
181+
/// register allocation.
182+
bool isValid() const;
173183
};
174184

175185
class LiveRegMatrixWrapperLegacy : public MachineFunctionPass {

llvm/lib/CodeGen/LiveRegMatrix.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212

1313
#include "llvm/CodeGen/LiveRegMatrix.h"
1414
#include "RegisterCoalescer.h"
15+
#include "llvm/ADT/DenseSet.h"
1516
#include "llvm/ADT/Statistic.h"
1617
#include "llvm/CodeGen/LiveInterval.h"
1718
#include "llvm/CodeGen/LiveIntervalUnion.h"
1819
#include "llvm/CodeGen/LiveIntervals.h"
1920
#include "llvm/CodeGen/MachineFunction.h"
21+
#include "llvm/CodeGen/MachineRegisterInfo.h"
2022
#include "llvm/CodeGen/TargetRegisterInfo.h"
2123
#include "llvm/CodeGen/TargetSubtargetInfo.h"
2224
#include "llvm/CodeGen/VirtRegMap.h"
@@ -290,6 +292,33 @@ Register LiveRegMatrix::getOneVReg(unsigned PhysReg) const {
290292
return MCRegister::NoRegister;
291293
}
292294

295+
bool LiveRegMatrix::isValid() const {
296+
// Build set of all valid LiveInterval pointers from LiveIntervals.
297+
DenseSet<LiveInterval *> ValidIntervals;
298+
for (unsigned RegIdx = 0, NumRegs = VRM->getRegInfo().getNumVirtRegs();
299+
RegIdx < NumRegs; ++RegIdx) {
300+
Register VReg = Register::index2VirtReg(RegIdx);
301+
// Only track assigned registers since unassigned ones won't be in Matrix
302+
if (VRM->hasPhys(VReg) && LIS->hasInterval(VReg))
303+
ValidIntervals.insert(&LIS->getInterval(VReg));
304+
}
305+
306+
// Now scan all LiveIntervalUnions in the matrix and verify each pointer
307+
unsigned NumDanglingPointers = 0;
308+
for (unsigned I = 0, Size = Matrix.size(); I != Size; ++I) {
309+
MCRegUnit Unit = static_cast<MCRegUnit>(I);
310+
for (const LiveInterval *LI : Matrix[Unit]) {
311+
if (!ValidIntervals.contains(LI)) {
312+
++NumDanglingPointers;
313+
dbgs() << "ERROR: LiveInterval pointer is not found in LiveIntervals:\n"
314+
<< " Register Unit: " << printRegUnit(Unit, TRI) << '\n'
315+
<< " LiveInterval pointer: " << LI << '\n';
316+
}
317+
}
318+
}
319+
return NumDanglingPointers == 0;
320+
}
321+
293322
AnalysisKey LiveRegMatrixAnalysis::Key;
294323

295324
LiveRegMatrix LiveRegMatrixAnalysis::run(MachineFunction &MF,

llvm/lib/CodeGen/RegAllocBase.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ void RegAllocBase::allocatePhysRegs() {
155155

156156
void RegAllocBase::postOptimization() {
157157
spiller().postOptimization();
158+
159+
// Verify LiveRegMatrix after spilling (no dangling pointers).
160+
assert(Matrix->isValid() && "LiveRegMatrix validation failed");
161+
158162
for (auto *DeadInst : DeadRemats) {
159163
LIS->RemoveMachineInstrFromMaps(*DeadInst);
160164
DeadInst->eraseFromParent();

0 commit comments

Comments
 (0)