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.3 PATCH] PR rtl-optimization/9771: Backport from mainline


PR rtl-optimization/9771 is a wrong-code regression on the 3.3 branch that
has previously been fixed on mainline and the 3.4 branch.  The following
patch is a backport of the 3.4 fix to the gcc-3_3-branch so that this PR
can finally be closed.

The following patch has been tested on i686-pc-linux-gnu with a full
"make bootstrap", all default languages except Ada, and regression tested
with a top-level "make -k check" with no new failures.

Ok to apply to the gcc-3_3-branch?



2004-11-29  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.160.4.6
diff -c -3 -p -r1.160.4.6 regclass.c
*** regclass.c	27 Nov 2004 16:59:13 -0000	1.160.4.6
--- regclass.c	29 Nov 2004 04:15:38 -0000
*************** static const char initial_call_used_regs
*** 105,110 ****
--- 105,117 ----
  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 ()
*** 447,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 || i == FRAME_POINTER_REGNUM)
  	;
  #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
        else if (i == HARD_FRAME_POINTER_REGNUM)
--- 454,464 ----
  	 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 ()
*** 461,473 ****
        else if (i == 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);
      }

--- 472,478 ----
        else if (i == 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 (i)
*** 792,797 ****
--- 797,808 ----

    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 (i)
*** 802,808 ****
    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
--- 813,818 ----


/* 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
--


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