http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60028
Bug ID: 60028 Summary: TIC6X: B3 register (return address) is saved on stack when real call is replaced with sibling call in a leaf function Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: wojtek.golf at interia dot pl GCC 4.8.2, target tic6x Input source: int e_fun(int arg); extern int e_int; void g_fun(void) { e_fun(e_int); } compiled with a command: -fleading-underscore -march=c674x -O2 -g0 -S main.c gives the following assembler code: _g_fun: sub .d2 B15, 8, B15 stw .d2t2 B3, *+B15(8) b .s1 (_e_fun) || ldw .d2t1 *+B14(_e_int), A4 ldw .d2t2 *+B15(8), B3 || add .s2 8, B15, B15 ;; sibcall to (_e_fun) occurs nop 4 where B3 is saved on the stack even though a branch is taken to _e_fun. Texas Instruments CGTools compiler v7.3.2 (cl6x --gcc -mv6740 --symdebug:none -k -n main.c) gives the following assembler code (CALLRET is an alias to B): _g_fun: CALLRET .S1 _e_fun ; |6| LDW .D2T1 *+DP(_e_int),A4 ; |6| NOP 4 $C$RL0: ; CALL-RETURN OCCURS {_e_fun} 0 ; |6| where B3 is not saved. Some investigation on my part leads to the function c6x_expand_call in the file gcc/gcc/config/c6x/c6x.c, where we see what may cause B3 being marked as used and hence saved on the stack prior to the branch: if (sibcall) { call_insn = emit_call_insn (call_insn); use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), gen_rtx_REG (Pmode, REG_B3)); } commenting out use_reg invocation makes gcc to generate the expected listing: _g_fun: b .s1 (_e_fun) || ldw .d2t1 *+B14(_e_int), A4 ;; sibcall to (_e_fun) occurs nop 5 I haven't tested yet whether removal of use_reg invocation causes any regression, but I'd like it to be investigated whether it should be removed altogether or protected with some extra execution condition. With best, Wojciech