On 1/10/2026 9:11 AM, Stefan Schulze Frielinghaus wrote:
From: Stefan Schulze Frielinghaus <[email protected]>
This fixes
t.c:6:1: error: unable to find a register to spill
6 | }
| ^
for target avr. In the PR we are given a patch which makes use of hard
register constraints in the machine description for divmodhi4. Prior
combine we have for the test from the PR
(insn 7 6 8 2 (parallel [
(set (reg:HI 46 [ _1 ])
(div:HI (reg/v:HI 44 [ k ])
(reg:HI 48)))
(set (reg:HI 47)
(mod:HI (reg/v:HI 44 [ k ])
(reg:HI 48)))
(clobber (scratch:HI))
(clobber (scratch:QI))
]) "t.c":5:5 602 {divmodhi4}
(expr_list:REG_DEAD (reg:HI 48)
(expr_list:REG_DEAD (reg/v:HI 44 [ k ])
(expr_list:REG_UNUSED (reg:HI 47)
(nil)))))
(insn 8 7 9 2 (set (reg:HI 22 r22)
(symbol_ref/f:HI ("*.LC0") [flags 0x2] <var_decl 0x3fff7950d10 *.LC0>))
"t.c":5:5 128 {*movhi_split}
(nil))
(insn 9 8 10 2 (set (reg:HI 24 r24)
(reg:HI 46 [ _1 ])) "t.c":5:5 128 {*movhi_split}
(expr_list:REG_DEAD (reg:HI 46 [ _1 ])
(nil)))
The patched instruction divmodhi4 constraints operand 2 (here pseudo
48) to hard register 22. Combine merges insn 7 into 9 by crossing a
hard register assignment of register 22.
(note 7 6 8 2 NOTE_INSN_DELETED)
(insn 8 7 9 2 (set (reg:HI 22 r22)
(symbol_ref/f:HI ("*.LC0") [flags 0x2] <var_decl 0x3fff7950d10 *.LC0>))
"t.c":5:5 128 {*movhi_split}
(nil))
(insn 9 8 10 2 (parallel [
(set (reg:HI 24 r24)
(div:HI (reg:HI 49 [ k ])
(reg:HI 48)))
(set (reg:HI 47)
(mod:HI (reg:HI 49 [ k ])
(reg:HI 48)))
(clobber (scratch:HI))
(clobber (scratch:QI))
]) "t.c":5:5 602 {divmodhi4}
(expr_list:REG_DEAD (reg:HI 48)
(expr_list:REG_DEAD (reg:HI 49 [ k ])
(nil))))
This leaves us with a conflict for pseudo 48 in the updated insn 9 since
register 22 is live here.
Fixed by pulling the sledge hammer and skipping any logical link if a
single register constraint is possibly involved. Ideally we would skip
based on the fact whether there is any usage of a hard register referred
by any single register constraint between INSN and USE_INSN during
combine.
gcc/ChangeLog:
* combine.cc (has_single_register_constraint_p): New function.
(create_log_links): Do not build LOG_LINKs between insns
containing single register constraints.
Yea, this is a lot like the problems we have with return values and more
generally classes with a single hard register. I would suggest looking
at can't combine_insn_p which has the likely_spilled checks in it.
Jeff