[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:
parent
d6a1064853
commit
dfb8d68fd1
4 changed files with 40 additions and 12 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
17
llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
Normal file
17
llvm/test/CodeGen/RISCV/regalloc-greedy-urgent-evict.ll
Normal 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
|
||||
}
|
||||
Loading…
Reference in a new issue