This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[3.4 PATCH] PR optimization/9771: Backport from mainline


The following is a backport of the fix for PR rtl-optimization/9771
from mainline to the gcc-3_4-branch.  9771 is an admittedly obscure
"wrong-code" bug that is a regression at least from gcc 2.96.  This
fix has been on mainline for a while without problems.

The following patch has been tested against the gcc-3_4-branch on
i686-pc-linux-gnu, with a full "make bootstrap", all default languages,
and regression tested with a top-level "make -k check" with no new
failures?

Ok for the gcc-3_4-branch?


2004-09-23  Roger Sayle  <roger@eyesopen.com>

	PR rtl-optimization/9771
	* regclass.c (CALL_REALLY_USED_REGNO_P): New macro to eliminate
	conditional compilation in init_reg_sets_1.
	(init_reg_sets_1): Let global_regs[i] take priority over the frame
	(but not stack) pointer exceptions to regs_invalidated_by_call.
	(globalize_reg): Globalizing a fixed register may need to update
	regs_invalidated_by_call.

	* gcc.dg/pr9771-1.c: New test case.


Index: regclass.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regclass.c,v
retrieving revision 1.183
diff -c -3 -p -r1.183 regclass.c
*** regclass.c	22 Dec 2003 18:23:15 -0000	1.183
--- regclass.c	22 Sep 2004 21:56:32 -0000
*************** static const char initial_call_used_regs
*** 103,108 ****
--- 103,115 ----
  char call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
  #endif

+ #ifdef CALL_REALLY_USED_REGISTERS
+ #define CALL_REALLY_USED_REGNO_P(X)  call_really_used_regs[X]
+ #else
+ #define CALL_REALLY_USED_REGNO_P(X)  call_used_regs[X]
+ #endif
+
+
  /* Indexed by hard register number, contains 1 for registers that are
     fixed use or call used registers that cannot hold quantities across
     calls even if we are willing to save and restore them.  call fixed
*************** init_reg_sets_1 (void)
*** 436,442 ****
  	 If we are generating PIC code, the PIC offset table register is
  	 preserved across calls, though the target can override that.  */

!       if (i == STACK_POINTER_REGNUM || i == FRAME_POINTER_REGNUM)
  	;
  #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
        else if (i == HARD_FRAME_POINTER_REGNUM)
--- 443,453 ----
  	 If we are generating PIC code, the PIC offset table register is
  	 preserved across calls, though the target can override that.  */

!       if (i == STACK_POINTER_REGNUM)
! 	;
!       else if (global_regs[i])
! 	SET_HARD_REG_BIT (regs_invalidated_by_call, i);
!       else if (i == FRAME_POINTER_REGNUM)
  	;
  #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
        else if (i == HARD_FRAME_POINTER_REGNUM)
*************** init_reg_sets_1 (void)
*** 450,462 ****
        else if (i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i])
  	;
  #endif
!       else if (0
! #ifdef CALL_REALLY_USED_REGISTERS
! 	       || call_really_used_regs[i]
! #else
! 	       || call_used_regs[i]
! #endif
! 	       || global_regs[i])
  	SET_HARD_REG_BIT (regs_invalidated_by_call, i);
      }

--- 461,467 ----
        else if (i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i])
  	;
  #endif
!       else if (CALL_REALLY_USED_REGNO_P (i))
  	SET_HARD_REG_BIT (regs_invalidated_by_call, i);
      }

*************** globalize_reg (int i)
*** 778,783 ****
--- 783,794 ----

    global_regs[i] = 1;

+   /* If we're globalizing the frame pointer, we need to set the
+      appropriate regs_invalidated_by_call bit, even if it's already
+      set in fixed_regs.  */
+   if (i != STACK_POINTER_REGNUM)
+     SET_HARD_REG_BIT (regs_invalidated_by_call, i);
+
    /* If already fixed, nothing else to do.  */
    if (fixed_regs[i])
      return;
*************** globalize_reg (int i)
*** 788,794 ****
    SET_HARD_REG_BIT (fixed_reg_set, i);
    SET_HARD_REG_BIT (call_used_reg_set, i);
    SET_HARD_REG_BIT (call_fixed_reg_set, i);
-   SET_HARD_REG_BIT (regs_invalidated_by_call, i);
  }

  /* Now the data and code for the `regclass' pass, which happens
--- 799,804 ----

/* PR rtl-optimization/9771 */
/* { dg-do run { target i?86-*-* } } */
/* { dg-options "-O2 -fomit-frame-pointer -ffixed-ebp" } */

extern void abort(void);
extern void exit(int);

register long *B asm ("ebp");

long x = 10;
long y = 20;

void bar(void)
{
  B = &y;
}

void foo()
{
  long *adr = B;
  long save = *adr;

  *adr = 123;

  bar();

  *adr = save;
}

int main()
{
  B = &x;

  foo();

  if (x != 10 || y != 20)
    abort();

  /* We can't return, as our caller may assume %ebp is preserved!  */
  /* We could save/restore it (like foo), but its easier to exit.  */
  exit(0);
}


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]