Skip to content

Commit 75aff78

Browse files
authored
RegAllocFast: Fix verifier errors after assigning to reserved registers (#128281)
1 parent b5dd1fe commit 75aff78

File tree

2 files changed

+27
-16
lines changed

2 files changed

+27
-16
lines changed

llvm/lib/CodeGen/RegAllocFast.cpp

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ class RegAllocFastImpl {
206206
bool Error = false; ///< Could not allocate.
207207

208208
explicit LiveReg(Register VirtReg) : VirtReg(VirtReg) {}
209+
explicit LiveReg() {}
209210

210211
unsigned getSparseSetIndex() const { return VirtReg.virtRegIndex(); }
211212
};
@@ -216,7 +217,7 @@ class RegAllocFastImpl {
216217
LiveRegMap LiveVirtRegs;
217218

218219
/// Stores assigned virtual registers present in the bundle MI.
219-
DenseMap<Register, MCPhysReg> BundleVirtRegsMap;
220+
DenseMap<Register, LiveReg> BundleVirtRegsMap;
220221

221222
DenseMap<unsigned, SmallVector<MachineOperand *, 2>> LiveDbgValueMap;
222223
/// List of DBG_VALUE that we encountered without the vreg being assigned
@@ -374,7 +375,8 @@ class RegAllocFastImpl {
374375
SmallSet<Register, 2> &PrologLiveIns) const;
375376

376377
void reloadAtBegin(MachineBasicBlock &MBB);
377-
bool setPhysReg(MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg);
378+
bool setPhysReg(MachineInstr &MI, MachineOperand &MO,
379+
const LiveReg &Assignment);
378380

379381
Register traceCopies(Register VirtReg) const;
380382
Register traceCopyChain(Register Reg) const;
@@ -1005,7 +1007,7 @@ void RegAllocFastImpl::allocVirtRegUndef(MachineOperand &MO) {
10051007
MO.setSubReg(0);
10061008
}
10071009
MO.setReg(PhysReg);
1008-
MO.setIsRenamable(true);
1010+
MO.setIsRenamable(!LRI->Error);
10091011
}
10101012

10111013
/// Variation of defineVirtReg() with special handling for livethrough regs
@@ -1109,10 +1111,10 @@ bool RegAllocFastImpl::defineVirtReg(MachineInstr &MI, unsigned OpNum,
11091111
LRI->Reloaded = false;
11101112
}
11111113
if (MI.getOpcode() == TargetOpcode::BUNDLE) {
1112-
BundleVirtRegsMap[VirtReg] = PhysReg;
1114+
BundleVirtRegsMap[VirtReg] = *LRI;
11131115
}
11141116
markRegUsedInInstr(PhysReg);
1115-
return setPhysReg(MI, MO, PhysReg);
1117+
return setPhysReg(MI, MO, *LRI);
11161118
}
11171119

11181120
/// Allocates a register for a VirtReg use.
@@ -1158,10 +1160,10 @@ bool RegAllocFastImpl::useVirtReg(MachineInstr &MI, MachineOperand &MO,
11581160
LRI->LastUse = &MI;
11591161

11601162
if (MI.getOpcode() == TargetOpcode::BUNDLE) {
1161-
BundleVirtRegsMap[VirtReg] = LRI->PhysReg;
1163+
BundleVirtRegsMap[VirtReg] = *LRI;
11621164
}
11631165
markRegUsedInInstr(LRI->PhysReg);
1164-
return setPhysReg(MI, MO, LRI->PhysReg);
1166+
return setPhysReg(MI, MO, *LRI);
11651167
}
11661168

11671169
/// Query a physical register to use as a filler in contexts where the
@@ -1215,16 +1217,27 @@ MCPhysReg RegAllocFastImpl::getErrorAssignment(const LiveReg &LR,
12151217
/// Changes operand OpNum in MI the refer the PhysReg, considering subregs.
12161218
/// \return true if MI's MachineOperands were re-arranged/invalidated.
12171219
bool RegAllocFastImpl::setPhysReg(MachineInstr &MI, MachineOperand &MO,
1218-
MCPhysReg PhysReg) {
1220+
const LiveReg &Assignment) {
1221+
MCPhysReg PhysReg = Assignment.PhysReg;
1222+
assert(PhysReg && "assignments should always be to a valid physreg");
1223+
1224+
if (LLVM_UNLIKELY(Assignment.Error)) {
1225+
// Make sure we don't set renamable in error scenarios, as we may have
1226+
// assigned to a reserved register.
1227+
if (MO.isUse())
1228+
MO.setIsUndef(true);
1229+
}
1230+
12191231
if (!MO.getSubReg()) {
12201232
MO.setReg(PhysReg);
1221-
MO.setIsRenamable(true);
1233+
MO.setIsRenamable(!Assignment.Error);
12221234
return false;
12231235
}
12241236

12251237
// Handle subregister index.
1226-
MO.setReg(PhysReg ? TRI->getSubReg(PhysReg, MO.getSubReg()) : MCRegister());
1227-
MO.setIsRenamable(true);
1238+
MO.setReg(TRI->getSubReg(PhysReg, MO.getSubReg()));
1239+
MO.setIsRenamable(!Assignment.Error);
1240+
12281241
// Note: We leave the subreg number around a little longer in case of defs.
12291242
// This is so that the register freeing logic in allocateInstruction can still
12301243
// recognize this as subregister defs. The code there will clear the number.
@@ -1706,7 +1719,7 @@ void RegAllocFastImpl::handleDebugValue(MachineInstr &MI) {
17061719
if (LRI != LiveVirtRegs.end() && LRI->PhysReg) {
17071720
// Update every use of Reg within MI.
17081721
for (auto &RegMO : DbgOps)
1709-
setPhysReg(MI, *RegMO, LRI->PhysReg);
1722+
setPhysReg(MI, *RegMO, *LRI);
17101723
} else {
17111724
DanglingDbgValues[Reg].push_back(&MI);
17121725
}
@@ -1729,8 +1742,7 @@ void RegAllocFastImpl::handleBundle(MachineInstr &MI) {
17291742
if (!Reg.isVirtual() || !shouldAllocateRegister(Reg))
17301743
continue;
17311744

1732-
DenseMap<Register, MCPhysReg>::iterator DI;
1733-
DI = BundleVirtRegsMap.find(Reg);
1745+
DenseMap<Register, LiveReg>::iterator DI = BundleVirtRegsMap.find(Reg);
17341746
assert(DI != BundleVirtRegsMap.end() && "Unassigned virtual register");
17351747

17361748
setPhysReg(MI, MO, DI->second);

llvm/test/CodeGen/AMDGPU/ran-out-of-registers-error-all-regs-reserved.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
; RUN: not llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 -vgpr-regalloc=greedy -verify-machineinstrs -filetype=null %s 2>&1 | FileCheck -implicit-check-not=error %s
22
; RUN: not llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 -vgpr-regalloc=basic -verify-machineinstrs -filetype=null %s 2>&1 | FileCheck -implicit-check-not=error %s
3-
; TODO: Fix verifier error after fast
4-
; TODO: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 -vgpr-regalloc=fast -verify-machineinstrs -filetype=null %s 2>&1 | FileCheck -implicit-check-not=error %s
3+
; RUN: not llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 -vgpr-regalloc=fast -verify-machineinstrs -filetype=null %s 2>&1 | FileCheck -implicit-check-not=error %s
54

65
declare <32 x i32> @llvm.amdgcn.mfma.i32.32x32x4i8(i32, i32, <32 x i32>, i32 immarg, i32 immarg, i32 immarg)
76

0 commit comments

Comments
 (0)