https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90553
Bug ID: 90553 Summary: Register allocation allocates post-incremented address-load of call to call-clobbered register Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: hp at gcc dot gnu.org Target Milestone: --- Target: cris-elf For this code, similar to the newlib newlib/libc/misc/init.c:__init_array function, IRA is responsible for allocating a call-clobbered register for the address to the array of functions to call. To wit, that register is then clobbered by the called function: extern void (*p []) (void); void f(int x) { int i; for (i = 0; i < x; i++) p[i](); } The generated code for cris-elf with -O2 for r271317 (leading ELF-assembly sugar elided): _f: subq 4,$sp move $srp,[$sp] subq 8,$sp movem $r1,[$sp] cmpq 1,$r10 blt .L1 move.d $r10,$r1 move.d _p,$r9 clear.d $r0 .L3: jsr [$r9+] addq 1,$r0 cmp.d $r0,$r1 bne .L3 nop .L1: movem [$sp+],$r1 jump [$sp+] To all those not fluent in CRIS assembly, in gcc-rtl, the call instruction is (from the 312r.final dump): (call_insn 16 14 17 (parallel [ (call (mem:QI (mem/f:SI (post_inc:SI (reg:SI 9 r9 [orig:27 ivtmp.7 ] [27])) [1 MEM[base: _8, offset: 0B]+0 S4 A8]) [0 *_1 S1 A8]) (const_int 0 [0])) (clobber (reg:SI 16 srp)) ]) "t.c":7:5 220 {*expanded_call_non_v32} (expr_list:REG_UNUSED (reg:SI 9 r9 [orig:27 ivtmp.7 ] [27]) (expr_list:REG_INC (reg:SI 9 r9 [orig:27 ivtmp.7 ] [27]) (expr_list:REG_CALL_DECL (nil) (nil)))) (nil)) That is, the address to call is loaded from the pointer in R9, which is post-incremented. The register R9 is call-clobbered and mentioned as such in CALL_USED_REGISTERS. In the IRA dump in 276r.ira, pseudo-register 27 is is allocated to register R9. Following ira-lives.c:process_bb_node_lives it's apparent that the post-increment addressing is handled as the register being read at the beginning of the call, and the updated value happening *after* the call. It's open whether gcc *should* be able to handle this construct (a trivial patch to ira-lives.c) or whether this should be deemed outside what gcc currently can handle regarding register-allocation (the post-incrementing to be disabled until post-reload and the documentation updated). I'l marking this middle-end for moment. There's a tested patch, to be posted.