[RegAlloc] consider urgent evict in evictInterference (#192631)

This assertion causes a crash in programs with high register pressure
when inline assembly is used.

```
    assert((ExtraInfo->getCascade(Intf->reg()) < Cascade ||
            VirtReg.isSpillable() < Intf->isSpillable()) &&
           "Cannot decrease cascade number, illegal eviction");
```

It should account for the case where an urgent eviction may result in
cascade being less than `ExtraInfo->getCascade(Intf->reg())`

---------

Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
This commit is contained in:
Piyou Chen 2026-05-06 12:23:41 +08:00 committed by GitHub
parent d6a1064853
commit dfb8d68fd1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 40 additions and 12 deletions

View file

@ -121,6 +121,10 @@ public:
/// 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);

View file

@ -188,6 +188,21 @@ 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 +293,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)

View file

@ -649,6 +649,8 @@ void RAGreedy::evictInterference(const LiveInterval &VirtReg,
Matrix->unassign(*Intf);
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);

View file

@ -0,0 +1,17 @@
; RUN: not llc -mtriple=riscv64 -mattr=+v,+zvfh -filetype=null %s 2>&1 | FileCheck %s
; CHECK: error: inline assembly requires more registers than available
define void @foo() {
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
}