This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[3.3 PATCH] PR rtl-optimization/9771: Backport from mainline
- From: Roger Sayle <roger at eyesopen dot com>
- To: Gabriel Dos Reis <gdr at cs dot tamu dot edu>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 29 Nov 2004 17:14:17 -0700 (MST)
- Subject: [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
--