Skip to content

Commit 21a94e8

Browse files
committed
RegAlloc: Fix failure on undef use when all registers are reserved
Greedy and fast would hit different assertions on undef uses if all registers in a class were reserved.
1 parent 8db7a16 commit 21a94e8

File tree

3 files changed

+17
-10
lines changed

3 files changed

+17
-10
lines changed

llvm/lib/CodeGen/RegAllocFast.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -982,16 +982,23 @@ void RegAllocFastImpl::allocVirtRegUndef(MachineOperand &MO) {
982982
if (!shouldAllocateRegister(VirtReg))
983983
return;
984984

985-
LiveRegMap::const_iterator LRI = findLiveVirtReg(VirtReg);
985+
LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
986986
MCPhysReg PhysReg;
987987
if (LRI != LiveVirtRegs.end() && LRI->PhysReg) {
988988
PhysReg = LRI->PhysReg;
989989
} else {
990990
const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg);
991991
ArrayRef<MCPhysReg> AllocationOrder = RegClassInfo.getOrder(&RC);
992-
// FIXME: This can happen, and should fall back to a reserved entry in RC.
993-
assert(!AllocationOrder.empty() && "Allocation order must not be empty");
994-
PhysReg = AllocationOrder[0];
992+
if (AllocationOrder.empty()) {
993+
// All registers in the class were reserved.
994+
//
995+
// It might be OK to take any entry from the class as this is an undef
996+
// use, but accepting this would give different behavior than greedy and
997+
// basic.
998+
PhysReg = getErrorAssignment(*LRI, *MO.getParent(), RC);
999+
LRI->Error = true;
1000+
} else
1001+
PhysReg = AllocationOrder[0];
9951002
}
9961003

9971004
unsigned SubRegIdx = MO.getSubReg();

llvm/lib/CodeGen/RegAllocGreedy.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2465,7 +2465,7 @@ MCRegister RAGreedy::selectOrSplitImpl(const LiveInterval &VirtReg,
24652465
return 0;
24662466
}
24672467

2468-
if (Stage < RS_Spill) {
2468+
if (Stage < RS_Spill && !VirtReg.empty()) {
24692469
// Try splitting VirtReg or interferences.
24702470
unsigned NewVRegSizeBefore = NewVRegs.size();
24712471
Register PhysReg = trySplit(VirtReg, Order, NewVRegs, FixedRegisters);

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ define <32 x i32> @no_registers_from_class_available_to_allocate_asm_def() #0 {
2424
ret <32 x i32> %ret
2525
}
2626

27-
; FIXME: Special case in fast RA, asserts. Also asserts in greedy
28-
; define void @no_registers_from_class_available_to_allocate_undef_asm() #0 {
29-
; call void asm sideeffect "; use $0", "v"(<32 x i32> poison)
30-
; ret void
31-
; }
27+
; CHECK: error: <unknown>:0:0: no registers from class available to allocate in function 'no_registers_from_class_available_to_allocate_undef_asm'
28+
define void @no_registers_from_class_available_to_allocate_undef_asm() #0 {
29+
call void asm sideeffect "; use $0", "v"(<32 x i32> poison)
30+
ret void
31+
}
3232

3333
attributes #0 = { "amdgpu-waves-per-eu"="10,10" }

0 commit comments

Comments
 (0)