http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46030
Summary: registers trashed with -Os Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassig...@gcc.gnu.org ReportedBy: amo...@gmail.com This comment in rs6000_savres_strategy But we can only use the out-of-line routines if we know that we've used store multiple or out-of-line routines in the prologue, i.e. if we've saved all the registers from first_gp_reg_save. Otherwise, we risk loading garbage from the stack. is true, but the code in rs6000_savres_strategy does not prevent this occurring. In fact, the "saved_all" code does precisely nothing. Found with gcc.c-torture/compile/20050119-1.c -m32 -Os -S. Note the inline save but use of _restgpr to restore. Doesn't actually cause a problem since there is only one register saved/restored here, but it's not hard to construct something that does trash a register, eg. /* Compile with -Os -mno-multiple */ void f2 (char *s) { int col = 0; char c; void f3 (char c) { extern int f4 (char); register long r25 __asm__ ("r25"); register long r27 __asm__ ("r27"); register long r28 __asm__ ("r28"); register long r29 __asm__ ("r29"); register long r31 __asm__ ("r31"); if (c == '\t') do f3 (' '); while (col % 8 != 0); else { __asm__ __volatile__ ("#uses %0 %1 %2 %3 %4" : "=r" (r25), "=r" (r27), "=r" (r28), "=r" (r29), "=r" (r31)); f4 (c); col++; } } while ((c = *s++) != 0) f3 (c); }