-
Notifications
You must be signed in to change notification settings - Fork 12.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RegAlloc: Fix failure on undef use when all registers are reserved #119647
RegAlloc: Fix failure on undef use when all registers are reserved #119647
Conversation
|
@llvm/pr-subscribers-backend-amdgpu Author: Matt Arsenault (arsenm) ChangesGreedy and fast would hit different assertions on undef uses if all Full diff: https://github.com/llvm/llvm-project/pull/119647.diff 3 Files Affected:
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/pr-subscribers-llvm-regalloc Author: Matt Arsenault (arsenm) ChangesGreedy and fast would hit different assertions on undef uses if all Full diff: https://github.com/llvm/llvm-project/pull/119647.diff 3 Files Affected:
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" }
|
8db7a16 to
edfb488
Compare
Greedy and fast would hit different assertions on undef uses if all registers in a class were reserved.
b1776bc to
be07817
Compare

Greedy and fast would hit different assertions on undef uses if all
registers in a class were reserved.