https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/119647
Greedy and fast would hit different assertions on undef uses if all registers in a class were reserved. >From 21a94e80ec529fac5a23febcdf738f01c56d0100 Mon Sep 17 00:00:00 2001 From: Matt Arsenault <matthew.arsena...@amd.com> Date: Thu, 12 Dec 2024 10:07:10 +0900 Subject: [PATCH] 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. --- llvm/lib/CodeGen/RegAllocFast.cpp | 15 +++++++++++---- llvm/lib/CodeGen/RegAllocGreedy.cpp | 2 +- ...an-out-of-registers-error-all-regs-reserved.ll | 10 +++++----- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp index 8323a050bcbc4a..87c0636fc45188 100644 --- a/llvm/lib/CodeGen/RegAllocFast.cpp +++ b/llvm/lib/CodeGen/RegAllocFast.cpp @@ -982,16 +982,23 @@ void RegAllocFastImpl::allocVirtRegUndef(MachineOperand &MO) { if (!shouldAllocateRegister(VirtReg)) return; - LiveRegMap::const_iterator LRI = findLiveVirtReg(VirtReg); + LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg); MCPhysReg PhysReg; if (LRI != LiveVirtRegs.end() && LRI->PhysReg) { PhysReg = LRI->PhysReg; } else { const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg); ArrayRef<MCPhysReg> AllocationOrder = RegClassInfo.getOrder(&RC); - // FIXME: This can happen, and should fall back to a reserved entry in RC. - assert(!AllocationOrder.empty() && "Allocation order must not be empty"); - PhysReg = AllocationOrder[0]; + if (AllocationOrder.empty()) { + // All registers in the class were reserved. + // + // It might be OK to take any entry from the class as this is an undef + // use, but accepting this would give different behavior than greedy and + // basic. + PhysReg = getErrorAssignment(*LRI, *MO.getParent(), RC); + LRI->Error = true; + } else + PhysReg = AllocationOrder[0]; } unsigned SubRegIdx = MO.getSubReg(); diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp index cb29218e966e06..af48e916feab45 100644 --- a/llvm/lib/CodeGen/RegAllocGreedy.cpp +++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -2465,7 +2465,7 @@ MCRegister RAGreedy::selectOrSplitImpl(const LiveInterval &VirtReg, return 0; } - if (Stage < RS_Spill) { + if (Stage < RS_Spill && !VirtReg.empty()) { // Try splitting VirtReg or interferences. unsigned NewVRegSizeBefore = NewVRegs.size(); Register PhysReg = trySplit(VirtReg, Order, NewVRegs, FixedRegisters); diff --git a/llvm/test/CodeGen/AMDGPU/ran-out-of-registers-error-all-regs-reserved.ll b/llvm/test/CodeGen/AMDGPU/ran-out-of-registers-error-all-regs-reserved.ll index 05975920ebeb8d..388a8e804a8896 100644 --- a/llvm/test/CodeGen/AMDGPU/ran-out-of-registers-error-all-regs-reserved.ll +++ b/llvm/test/CodeGen/AMDGPU/ran-out-of-registers-error-all-regs-reserved.ll @@ -24,10 +24,10 @@ define <32 x i32> @no_registers_from_class_available_to_allocate_asm_def() #0 { ret <32 x i32> %ret } -; FIXME: Special case in fast RA, asserts. Also asserts in greedy -; define void @no_registers_from_class_available_to_allocate_undef_asm() #0 { -; call void asm sideeffect "; use $0", "v"(<32 x i32> poison) -; ret void -; } +; CHECK: error: <unknown>:0:0: no registers from class available to allocate in function 'no_registers_from_class_available_to_allocate_undef_asm' +define void @no_registers_from_class_available_to_allocate_undef_asm() #0 { + call void asm sideeffect "; use $0", "v"(<32 x i32> poison) + ret void +} attributes #0 = { "amdgpu-waves-per-eu"="10,10" } _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits