[llvm-branch-commits] [llvm] RegAlloc: Fix failure on undef use when all registers are reserved (PR #119647)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Dec 11 17:53:22 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-regalloc
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
Greedy and fast would hit different assertions on undef uses if all
registers in a class were reserved.
---
Full diff: https://github.com/llvm/llvm-project/pull/119647.diff
3 Files Affected:
- (modified) llvm/lib/CodeGen/RegAllocFast.cpp (+11-4)
- (modified) llvm/lib/CodeGen/RegAllocGreedy.cpp (+1-1)
- (modified) llvm/test/CodeGen/AMDGPU/ran-out-of-registers-error-all-regs-reserved.ll (+5-5)
``````````diff
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" }
``````````
</details>
https://github.com/llvm/llvm-project/pull/119647
More information about the llvm-branch-commits
mailing list