[llvm] [RegAlloc] consider urgent evict in evictInterference (PR #192631)
Piyou Chen via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 28 00:24:08 PDT 2026
https://github.com/BeMg updated https://github.com/llvm/llvm-project/pull/192631
>From 551e4950ca3705053f8ec80690935760cfb43415 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Fri, 17 Apr 2026 02:24:06 -0700
Subject: [PATCH 1/7] [RegAlloc] consider urgent evict in evictInterference
This assertion cause crash for highly pressure inline asm program.
assert((ExtraInfo->getCascade(Intf->reg()) < Cascade ||
VirtReg.isSpillable() < Intf->isSpillable()) &&
"Cannot decrease cascade number, illegal eviction");
It should consider the urgent evict situation may make Cascade < (ExtraInfo->getCascade(Intf->reg())
---
llvm/lib/CodeGen/RegAllocGreedy.cpp | 8 +++++++
.../RISCV/regalloc-greedy-urgent-evict.ll | 21 +++++++++++++++++++
2 files changed, 29 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index dd86fa127e6dc..8436374f3defe 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -648,7 +648,15 @@ void RAGreedy::evictInterference(const LiveInterval &VirtReg,
continue;
Matrix->unassign(*Intf);
+ // Urgent eviction will break the cascade assumption.
+ // Should sync with canEvictInterferenceBasedOnCost
+ bool Urgent =
+ !VirtReg.isSpillable() &&
+ (Intf->isSpillable() ||
+ RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(VirtReg.reg())) <
+ RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(Intf->reg())));
assert((ExtraInfo->getCascade(Intf->reg()) < Cascade ||
+ (Cascade < ExtraInfo->getCascade(Intf->reg()) && Urgent) ||
VirtReg.isSpillable() < Intf->isSpillable()) &&
"Cannot decrease cascade number, illegal eviction");
ExtraInfo->setCascade(Intf->reg(), Cascade);
diff --git a/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll b/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
new file mode 100644
index 0000000000000..a8c50b7881ef6
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
@@ -0,0 +1,21 @@
+; RUN: not llc -mtriple=riscv64 -mattr=+v,+zvfh -O1 < %s 2>&1 | FileCheck %s
+
+; CHECK: error: inline assembly requires more registers than available
+
+target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
+target triple = "riscv64-unknown-linux-gnu"
+
+define void @foo() #0 {
+entry:
+ br label %for.body3.us312
+
+for.body3.us312: ; preds = %for.body3.us312, %entry
+ %acc0.1303.us = phi <vscale x 16 x float> [ zeroinitializer, %entry ], [ %asmresult152.us, %for.body3.us312 ]
+ %acc1.1302.us = phi <vscale x 16 x float> [ zeroinitializer, %entry ], [ %asmresult153.us, %for.body3.us312 ]
+ %0 = tail call { half, half, <vscale x 16 x half>, <vscale x 16 x float>, <vscale x 16 x float>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half> } asm sideeffect "\0A\09flh $0, 0($26) \0A\09flh $1, 0($27) \0A\09vsetvli zero, $28, e16, m4, ta, ma \0A\09vle16.v $2, ($29) \0A\09vfwadd.vf $3, $2, $0 \0A\09vfwsub.vf $4, $2, $1 \0A\09flh $5, 0($30) \0A\09flh $6, 0($31) \0A\09vle16.v $7, ($32) \0A\09vfwmul.vf $3, $7, $5 \0A\09vfwadd.vf $4, $7, $6 \0A\09flh $8, 0($33) \0A\09flh $9, 0($34) \0A\09vle16.v $10, ($35) \0A\09vfwsub.vf $3, $10, $8 \0A\09vfwmul.vf $4, $10, $9 \0A\09flh $11, 0($36) \0A\09flh $12, 0($37) \0A\09vle16.v $13, ($38) \0A\09vfwadd.vf $3, $13, $11 \0A\09vfwsub.vf $4, $13, $12 \0A\09flh $14, 0($39) \0A\09flh $15, 0($40) \0A\09vle16.v $16, ($41) \0A\09vfwmul.vf $3, $16, $14 \0A\09vfwadd.vf $4, $16, $15 \0A\09flh $17, 0($42) \0A\09flh $18, 0($43) \0A\09vle16.v $19, ($44) \0A\09vfwsub.vf $3, $19, $17 \0A\09vfwmul.vf $4, $19, $18 \0A\09flh $20, 0($45) \0A\09flh $21, 0($46) \0A\09vle16.v $22, ($47) \0A\09vfwadd.vf $3, $22, $20 \0A\09vfwsub.vf $4, $22, $21 \0A\09flh $23, 0($48) \0A\09flh $24, 0($49) \0A\09vle16.v $25, ($50) \0A\09vfwmul.vf $3, $25, $23 \0A\09vfwadd.vf $4, $25, $24 \0A\09", "=&f,=&f,=&^vr,=&^vr,=&^vr,=&f,=&f,=&^vr,=&f,=&f,=&^vr,=&f,=&f,=&^vr,=&f,=&f,=&^vr,=&f,=&f,=&^vr,=&f,=&f,=&^vr,=&f,=&f,=&^vr,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,3,4,~{vtype},~{vl},~{memory},~{vl},~{vtype}"(ptr null, ptr null, i64 0, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, <vscale x 16 x float> %acc0.1303.us, <vscale x 16 x float> %acc1.1302.us)
+ %asmresult152.us = extractvalue { half, half, <vscale x 16 x half>, <vscale x 16 x float>, <vscale x 16 x float>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half> } %0, 3
+ %asmresult153.us = extractvalue { half, half, <vscale x 16 x half>, <vscale x 16 x float>, <vscale x 16 x float>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half> } %0, 4
+ br label %for.body3.us312
+}
+
+attributes #0 = { "target-features"="+zvfh" }
>From 35728ee8a2d5fc13b598e9b408922c11308e3f34 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Sun, 19 Apr 2026 20:57:06 -0700
Subject: [PATCH 2/7] Drop the O1 and attr
---
llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll b/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
index a8c50b7881ef6..7236586580d4e 100644
--- a/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
+++ b/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
@@ -1,11 +1,11 @@
-; RUN: not llc -mtriple=riscv64 -mattr=+v,+zvfh -O1 < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple=riscv64 -mattr=+v,+zvfh < %s 2>&1 | FileCheck %s
; CHECK: error: inline assembly requires more registers than available
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-linux-gnu"
-define void @foo() #0 {
+define void @foo() {
entry:
br label %for.body3.us312
@@ -17,5 +17,3 @@ for.body3.us312: ; preds = %for.body3.us312, %e
%asmresult153.us = extractvalue { half, half, <vscale x 16 x half>, <vscale x 16 x float>, <vscale x 16 x float>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half>, half, half, <vscale x 16 x half> } %0, 4
br label %for.body3.us312
}
-
-attributes #0 = { "target-features"="+zvfh" }
>From 5a818f71882ccad222fc4e0196014c4acde226ff Mon Sep 17 00:00:00 2001
From: Piyou Chen <gccbg04538 at gmail.com>
Date: Wed, 22 Apr 2026 11:18:06 +0800
Subject: [PATCH 3/7] Update
llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
Drop the Triple
Co-authored-by: Matt Arsenault <arsenm2 at gmail.com>
---
llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll | 2 --
1 file changed, 2 deletions(-)
diff --git a/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll b/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
index 7236586580d4e..08c13eebe80d6 100644
--- a/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
+++ b/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
@@ -2,8 +2,6 @@
; CHECK: error: inline assembly requires more registers than available
-target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
-target triple = "riscv64-unknown-linux-gnu"
define void @foo() {
entry:
>From 78758e74d94b930ebd414f1e668dbf7010c7b3fb Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Tue, 21 Apr 2026 21:54:13 -0700
Subject: [PATCH 4/7] Make the helper function inside RegAllocEvictionAdvisor
---
.../llvm/CodeGen/RegAllocEvictionAdvisor.h | 4 +++
llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp | 30 +++++++++++--------
llvm/lib/CodeGen/RegAllocGreedy.cpp | 8 +----
3 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/RegAllocEvictionAdvisor.h b/llvm/include/llvm/CodeGen/RegAllocEvictionAdvisor.h
index 1020c5f97dd31..c965854c93b92 100644
--- a/llvm/include/llvm/CodeGen/RegAllocEvictionAdvisor.h
+++ b/llvm/include/llvm/CodeGen/RegAllocEvictionAdvisor.h
@@ -121,6 +121,10 @@ class RegAllocEvictionAdvisor {
/// not been used for allocation yet.
bool isUnusedCalleeSavedReg(MCRegister PhysReg) const;
+ /// Returns true if this is an urgent eviction.
+ bool isUrgentEviction(const LiveInterval &VirtReg,
+ const LiveInterval &Intf) const;
+
protected:
RegAllocEvictionAdvisor(const MachineFunction &MF, const RAGreedy &RA);
diff --git a/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp
index f2c2f74755ace..e0e087bd851c4 100644
--- a/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp
+++ b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp
@@ -188,6 +188,22 @@ RegAllocEvictionAdvisor::RegAllocEvictionAdvisor(const MachineFunction &MF,
MF.getSubtarget().enableRALocalReassignment(
MF.getTarget().getOptLevel())) {}
+/// isUrgentEviction - Returns true if this is an urgent eviction. Once a live
+/// range becomes small enough, it is urgent that we find a register for it.
+/// This is indicated by an infinite spill weight. These urgent live ranges
+/// get to evict almost anything.
+///
+/// Also allow urgent evictions of unspillable ranges from a strictly larger
+/// allocation order.
+bool RegAllocEvictionAdvisor::isUrgentEviction(
+ const LiveInterval &VirtReg, const LiveInterval &Intf) const {
+ return !VirtReg.isSpillable() &&
+ (Intf.isSpillable() ||
+ RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(VirtReg.reg())) <
+ RegClassInfo.getNumAllocatableRegs(
+ MRI->getRegClass(Intf.reg())));
+}
+
/// shouldEvict - determine if A should evict the assigned live range B. The
/// eviction policy defined by this function together with the allocation order
/// defined by enqueue() decides which registers ultimately end up being split
@@ -278,18 +294,8 @@ bool DefaultEvictionAdvisor::canEvictInterferenceBasedOnCost(
// Never evict spill products. They cannot split or spill.
if (RA.getExtraInfo().getStage(*Intf) == RS_Done)
return false;
- // Once a live range becomes small enough, it is urgent that we find a
- // register for it. This is indicated by an infinite spill weight. These
- // urgent live ranges get to evict almost anything.
- //
- // Also allow urgent evictions of unspillable ranges from a strictly
- // larger allocation order.
- bool Urgent =
- !VirtReg.isSpillable() &&
- (Intf->isSpillable() ||
- RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(VirtReg.reg())) <
- RegClassInfo.getNumAllocatableRegs(
- MRI->getRegClass(Intf->reg())));
+
+ bool Urgent = isUrgentEviction(VirtReg, *Intf);
// Only evict older cascades or live ranges without a cascade.
unsigned IntfCascade = RA.getExtraInfo().getCascade(Intf->reg());
if (Cascade == IntfCascade)
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 8436374f3defe..3b495a33a2d62 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -648,13 +648,7 @@ void RAGreedy::evictInterference(const LiveInterval &VirtReg,
continue;
Matrix->unassign(*Intf);
- // Urgent eviction will break the cascade assumption.
- // Should sync with canEvictInterferenceBasedOnCost
- bool Urgent =
- !VirtReg.isSpillable() &&
- (Intf->isSpillable() ||
- RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(VirtReg.reg())) <
- RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(Intf->reg())));
+ bool Urgent = EvictAdvisor->isUrgentEviction(VirtReg, *Intf);
assert((ExtraInfo->getCascade(Intf->reg()) < Cascade ||
(Cascade < ExtraInfo->getCascade(Intf->reg()) && Urgent) ||
VirtReg.isSpillable() < Intf->isSpillable()) &&
>From d1d60495a51b8efac1bed692cb62d29df526156e Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Wed, 22 Apr 2026 21:13:09 -0700
Subject: [PATCH 5/7] Fixup format
---
llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp
index e0e087bd851c4..7734d66f6b42c 100644
--- a/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp
+++ b/llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp
@@ -195,13 +195,12 @@ RegAllocEvictionAdvisor::RegAllocEvictionAdvisor(const MachineFunction &MF,
///
/// Also allow urgent evictions of unspillable ranges from a strictly larger
/// allocation order.
-bool RegAllocEvictionAdvisor::isUrgentEviction(
- const LiveInterval &VirtReg, const LiveInterval &Intf) const {
+bool RegAllocEvictionAdvisor::isUrgentEviction(const LiveInterval &VirtReg,
+ const LiveInterval &Intf) const {
return !VirtReg.isSpillable() &&
(Intf.isSpillable() ||
RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(VirtReg.reg())) <
- RegClassInfo.getNumAllocatableRegs(
- MRI->getRegClass(Intf.reg())));
+ RegClassInfo.getNumAllocatableRegs(MRI->getRegClass(Intf.reg())));
}
/// shouldEvict - determine if A should evict the assigned live range B. The
>From d0a3b9ce2524fb4c9f4f354dc338d21bbb3adb69 Mon Sep 17 00:00:00 2001
From: Piyou Chen <gccbg04538 at gmail.com>
Date: Tue, 28 Apr 2026 15:23:43 +0800
Subject: [PATCH 6/7] Update llvm/lib/CodeGen/RegAllocGreedy.cpp
Co-authored-by: Matt Arsenault <arsenm2 at gmail.com>
---
llvm/lib/CodeGen/RegAllocGreedy.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index 3b495a33a2d62..935f2dc0a2731 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -648,9 +648,8 @@ void RAGreedy::evictInterference(const LiveInterval &VirtReg,
continue;
Matrix->unassign(*Intf);
- bool Urgent = EvictAdvisor->isUrgentEviction(VirtReg, *Intf);
- assert((ExtraInfo->getCascade(Intf->reg()) < Cascade ||
- (Cascade < ExtraInfo->getCascade(Intf->reg()) && Urgent) ||
+assert((ExtraInfo->getCascade(Intf->reg()) < Cascade ||
+ (Cascade < ExtraInfo->getCascade(Intf->reg()) && EvictAdvisor->isUrgentEviction(VirtReg, *Intf)) ||
VirtReg.isSpillable() < Intf->isSpillable()) &&
"Cannot decrease cascade number, illegal eviction");
ExtraInfo->setCascade(Intf->reg(), Cascade);
>From bc48d409b691d8ed0ee244c85a6c495129553dba Mon Sep 17 00:00:00 2001
From: Piyou Chen <gccbg04538 at gmail.com>
Date: Tue, 28 Apr 2026 15:23:56 +0800
Subject: [PATCH 7/7] Update
llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
Co-authored-by: Matt Arsenault <arsenm2 at gmail.com>
---
llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll b/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
index 08c13eebe80d6..96574dafb57e3 100644
--- a/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
+++ b/llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
@@ -1,4 +1,4 @@
-; RUN: not llc -mtriple=riscv64 -mattr=+v,+zvfh < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple=riscv64 -mattr=+v,+zvfh -filetype=null %s 2>&1 | FileCheck %s
; CHECK: error: inline assembly requires more registers than available
More information about the llvm-commits
mailing list