https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125518
Bug ID: 125518
Summary: [RA]: lunable to find a register to spill: internal
compiler error: in lra_split_hard_reg_for, at
lra-assigns.cc:1885
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: gjl at gcc dot gnu.org
Target Milestone: ---
Created attachment 64595
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64595&action=edit
spill1-rtl.c: C-RTL test case (spill fail)
The attached spill1-rtl.c runs into a spill fail:
$ avr-gcc spill1-rtl.c -S -Os
spill1-rtl.c: In function 'foo':
spill1-rtl.c:58:1: error: unable to find a register to spill
58 | }
| ^
spill1-rtl.c:58:1: error: this is the insn:
(insn 7 23 19 2 (parallel [
(set (reg:HI 53 [orig:47 _1 ] [47])
(div:HI (reg/v:HI 45 [ var ])
(reg:HI 54 [49])))
(set (reg:HI 55 [48])
(mod:HI (reg/v:HI 45 [ var ])
(reg:HI 54 [49])))
(clobber (reg:HI 56 [50]))
(clobber (reg:QI 57 [51]))
]) 600 {divmodhi4}
(expr_list:REG_UNUSED (reg:QI 57 [51])
(expr_list:REG_UNUSED (reg:HI 56 [50])
(expr_list:REG_UNUSED (reg:HI 55 [48])
(expr_list:REG_DEAD (reg:HI 54 [49])
(expr_list:REG_DEAD (reg/v:HI 45 [ var ])
(nil)))))))
during RTL pass: reload
spill1-rtl.c:58:1: internal compiler error: in lra_split_hard_reg_for, at
lra-assigns.cc:1885
The equivalent C code is:
int bar (int, int);
int foo (int var)
{
return bar (var / 5, 0);
}
What the CRTL does is basically, that in preparation for the call, it
1) Sets the 2nd argument: reg22:HI=0 ; cinsn 8
2) Calculates the 1st argument using divmodhi4:
reg<6>:HI=5 ; cinsn 6
parallel (reg<4>:HI=div:HI (reg<2>:HI, reg<6>:HI) ; cinsn 7
reg<5>:HI=mod:HI (reg<2>:HI, reg<6>:HI)
clobber:HI
clobber:QI)
reg24:HI=reg<4>:HI ; cinsn 9
This is completely valid non-strict RTL, see for example this discussion:
https://gcc.gnu.org/pipermail/gcc/2026-May/248268.html
The challenge is that since r17-891, avr.md::divmodhi4 is using hard-reg
constraints:
(define_insn_and_split "divmodhi4"
[(set (match_operand:HI 0 "register_operand" "={r22}")
(div:HI (match_operand:HI 1 "register_operand" "{r24}")
(match_operand:HI 2 "register_operand" "{r22}")))
(set (match_operand:HI 3 "register_operand" "={r24}")
(mod:HI (match_dup 1)
(match_dup 2)))
(clobber (match_scratch:HI 4 "={r26}"))
(clobber (match_scratch:QI 5 "={r21}"))]
and hence it sets R22:HI as a side effect. RA should spill R22 prior to cinsn
7, or it should rematerialize R22:HI=0 after cinsn 7.
Currently, the testcase is not reachable from C since insn combine is rejecting
any combination that involves hard-reg constraints as of r17-438. This means
fixing the current PR is needed so insns with hard-reg constraints can be
insn-combined.