[Bug target/46030] New: registers trashed with -Os

amodra at gmail dot com gcc-bugzilla@gcc.gnu.org
Fri Oct 15 00:47:00 GMT 2010


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: unassigned@gcc.gnu.org
        ReportedBy: amodra@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);
}



More information about the Gcc-bugs mailing list