https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118103
Richard Sandiford <rsandifo at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|ASSIGNED |NEW
Assignee|rsandifo at gcc dot gnu.org |unassigned at gcc dot
gnu.org
--- Comment #7 from Richard Sandiford <rsandifo at gcc dot gnu.org> ---
The problem seems to be in the modelling of the FRM register.
CALL_USED_REGISTERS says that the register is call-clobbered/caller-save, which
means:
(a) it is not treated as live on entry to the function
(b) all calls are assumed to clobber the contents
So in:
;; entry block defs 1 [ra] 2 [sp] 10 [a0] 11 [a1] 12 [a2] 13 [a3] 14 [a4]
15 [a5] 16 [a6] 17 [a7] 42 [fa0] 43 [fa1] 44 [fa2] 45 [fa3] 46 [fa4] 47 [fa5]
48 [fa6] 49 [fa7]
…
(note 63 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
(note 2 63 10 2 NOTE_INSN_FUNCTION_BEG)
(call_insn 10 2 68 2 (parallel [
(call (mem:SI (symbol_ref:DI ("initialize") [flags 0x3]
<function_decl … initialize>) [0 initialize S4 A32])
(const_int 0 [0]))
(use (unspec:SI [
(const_int 0 [0])
] UNSPEC_CALLEE_CC))
(clobber (reg:SI 1 ra))
]) "/tmp/a.c":30:3 456 {call_internal}
(expr_list:REG_CALL_DECL (symbol_ref:DI ("initialize") [flags 0x3]
<function_decl … initialize>)
(expr_list:REG_EH_REGION (const_int 0 [0])
(nil)))
(nil))
(insn 68 10 3 2 (set (reg:SI 10 a0 [165])
(reg:SI 69 frm)) "/tmp/a.c":18:36 2725 {frrmsi}
(nil))
the FRM on entry to insn 68 is in a sense doubly undefined: it wasn't defined
on entry, and any value that it did have is in any case clobbered by the call.
If FRM is in fact a call-preserved/callee-save register, that should be
described using CALL_REALLY_USED_REGISTERS. If instead FRM is a
cooperatively-managed global register, global_regs[FRM_REGNUM] should be set to
true.