https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109910

            Bug ID: 109910
           Summary: GCC prologue/epilogue saves/restores callee-saved
                    registers that are never changed
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: other
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gjl at gcc dot gnu.org
  Target Milestone: ---

Created attachment 55120
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55120&action=edit
args.c: C test case.

There are targets like AVR that can pass values in callee-saved registers. 
There is no need to save / restore them if a caller never changes them. 
Example:

$ avr-gcc args.c -dp -mmcu=atmega128 -S -Os

typedef __UINT64_TYPE__ uint64_t;

void callee_ld (long double, long double);
void callee_ull (uint64_t, uint64_t);

void noop_ld (long double x, long double y)
{
    callee_ld (x, y);
}

void noop_ull (uint64_t x, uint64_t y)
{
    callee_ull (x, y);
}

y is passed in R10...R17 which are callee-saved:

noop_ld:
        push r10                 ;  73  [c=4 l=1]  pushqi1/0
        push r11                 ;  74  [c=4 l=1]  pushqi1/0
        push r12                 ;  75  [c=4 l=1]  pushqi1/0
        push r13                 ;  76  [c=4 l=1]  pushqi1/0
        push r14                 ;  77  [c=4 l=1]  pushqi1/0
        push r15                 ;  78  [c=4 l=1]  pushqi1/0
        push r16                 ;  79  [c=4 l=1]  pushqi1/0
        push r17                 ;  80  [c=4 l=1]  pushqi1/0
        call callee_ld   ;  39  [c=0 l=2]  call_insn/1
        pop r17          ;  83  [c=4 l=1]  popqi
        pop r16          ;  84  [c=4 l=1]  popqi
        pop r15          ;  85  [c=4 l=1]  popqi
        pop r14          ;  86  [c=4 l=1]  popqi
        pop r13          ;  87  [c=4 l=1]  popqi
        pop r12          ;  88  [c=4 l=1]  popqi
        pop r11          ;  89  [c=4 l=1]  popqi
        pop r10          ;  90  [c=4 l=1]  popqi
        ret              ;  91  [c=0 l=1]  return_from_epilogue

There is no need to save R10..R17 because they are never changed.  If any of
these regs is changed by callee_ld, that function will take care of it because
these regs are callee-saved.

No need to mention that this adds considerably to code size, compute and stack
usage.

The AVR backend uses df_regs_ever_live_p to determine whether a register must
be saved / restored in lack of a better alternative like non-existing
df_regs_ever_changed_p.

Configured with: ../../source/gcc-master/configure --target=avr --disable-nls
--with-dwarf2 --with-gnu-as --with-gnu-ld --disable-shared
--enable-languages=c,c++

gcc version 14.0.0 20230518 (experimental) (GCC)

Reply via email to