gcc.dg/20020312-2.c starts to fail after the revision 144964 on sh. sh.c:calc_live_regs always saves the regs ever live, even they are global. After 144964, we get more correct live information for global regs and it reveals the issue. Another tiny test case is
register void *reg __asm__("r10"); void f (void) { reg = 0; } which was compiled to f: mov.l r14,@-r15 mov #0,r10 mov r15,r14 mov r14,r15 rts mov.l @r15+,r14 before 144964, and now is compiled to f: mov.l r10,@-r15 mov.l r14,@-r15 mov r15,r14 mov r14,r15 mov.l @r15+,r14 rts mov.l @r15+,r10 I'm testing the patch below. diff -up ORIG/trunk/gcc/config/sh/sh.c trunk/gcc/config/sh/sh.c --- ORIG/trunk/gcc/config/sh/sh.c 2008-10-31 19:18:54.000000000 +0900 +++ trunk/gcc/config/sh/sh.c 2009-03-22 06:45:12.000000000 +0900 @@ -5966,7 +5966,9 @@ calc_live_regs (HARD_REG_SET *live_regs_ && crtl->args.info.call_cookie && reg == PIC_OFFSET_TABLE_REGNUM) || (df_regs_ever_live_p (reg) - && (!call_really_used_regs[reg] + && ((!call_really_used_regs[reg] + && !(reg != PIC_OFFSET_TABLE_REGNUM + && fixed_regs[reg] && call_used_regs[reg])) || (trapa_handler && reg == FPSCR_REG && TARGET_FPU_ANY))) || (crtl->calls_eh_return && (reg == EH_RETURN_DATA_REGNO (0) -- Summary: [4.4 Regression] SH: global registers are wrongly saved Product: gcc Version: 4.4.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: target AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: kkojima at gcc dot gnu dot org GCC target triplet: sh4-unknown-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39523