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)