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.

Reply via email to