Skip to content

Commit 2f1df05

Browse files
committed
RegAllocFast: Fix verifier errors after assigning to reserved registers
1 parent b5dd1fe commit 2f1df05

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed

llvm/lib/CodeGen/RegAllocFast.cpp

Lines changed: 27 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,8 @@ void RegAllocFastImpl::allocVirtRegUndef(MachineOperand &MO) {
10051007
MO.setSubReg(0);
10061008
}
10071009
MO.setReg(PhysReg);
1008-
MO.setIsRenamable(true);
1010+
if (!LRI->Error)
1011+
MO.setIsRenamable(true);
10091012
}
10101013

10111014
/// Variation of defineVirtReg() with special handling for livethrough regs
@@ -1109,10 +1112,10 @@ bool RegAllocFastImpl::defineVirtReg(MachineInstr &MI, unsigned OpNum,
11091112
LRI->Reloaded = false;
11101113
}
11111114
if (MI.getOpcode() == TargetOpcode::BUNDLE) {
1112-
BundleVirtRegsMap[VirtReg] = PhysReg;
1115+
BundleVirtRegsMap[VirtReg] = *LRI;
11131116
}
11141117
markRegUsedInInstr(PhysReg);
1115-
return setPhysReg(MI, MO, PhysReg);
1118+
return setPhysReg(MI, MO, *LRI);
11161119
}
11171120

11181121
/// Allocates a register for a VirtReg use.
@@ -1158,10 +1161,10 @@ bool RegAllocFastImpl::useVirtReg(MachineInstr &MI, MachineOperand &MO,
11581161
LRI->LastUse = &MI;
11591162

11601163
if (MI.getOpcode() == TargetOpcode::BUNDLE) {
1161-
BundleVirtRegsMap[VirtReg] = LRI->PhysReg;
1164+
BundleVirtRegsMap[VirtReg] = *LRI;
11621165
}
11631166
markRegUsedInInstr(LRI->PhysReg);
1164-
return setPhysReg(MI, MO, LRI->PhysReg);
1167+
return setPhysReg(MI, MO, *LRI);
11651168
}
11661169

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

12251238
// Handle subregister index.
1226-
MO.setReg(PhysReg ? TRI->getSubReg(PhysReg, MO.getSubReg()) : MCRegister());
1227-
MO.setIsRenamable(true);
1239+
MO.setReg(TRI->getSubReg(PhysReg, MO.getSubReg()));
1240+
MO.setIsRenamable(!Assignment.Error);
1241+
12281242
// Note: We leave the subreg number around a little longer in case of defs.
12291243
// This is so that the register freeing logic in allocateInstruction can still
12301244
// recognize this as subregister defs. The code there will clear the number.
@@ -1706,7 +1720,7 @@ void RegAllocFastImpl::handleDebugValue(MachineInstr &MI) {
17061720
if (LRI != LiveVirtRegs.end() && LRI->PhysReg) {
17071721
// Update every use of Reg within MI.
17081722
for (auto &RegMO : DbgOps)
1709-
setPhysReg(MI, *RegMO, LRI->PhysReg);
1723+
setPhysReg(MI, *RegMO, *LRI);
17101724
} else {
17111725
DanglingDbgValues[Reg].push_back(&MI);
17121726
}
@@ -1729,8 +1743,7 @@ void RegAllocFastImpl::handleBundle(MachineInstr &MI) {
17291743
if (!Reg.isVirtual() || !shouldAllocateRegister(Reg))
17301744
continue;
17311745

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

17361749
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)