mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-16 13:30:13 +08:00
re PR middle-end/54921 (wrong code with -Os -fno-omit-frame-pointer -fsched2-use-superblocks -fstack-protector -ftree-slp-vectorize)
PR rtl-optimization/54921 * cselib.h (fp_setter_insn): New prototype. * cselib.c (fp_setter_insn): New function. (cselib_process_insn): If frame_pointer_needed, call cselib_invalidate_rtx (stack_pointer_rtx) after processing a frame pointer setter. * var-tracking.c (fp_setter): Removed. (vt_initialize): Use fp_setter_insn instead of fp_setter. * gcc.dg/pr54921.c: New test. From-SVN: r193647
This commit is contained in:
parent
4ced1d6de8
commit
40155239d6
@ -1,3 +1,14 @@
|
||||
2012-11-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/54921
|
||||
* cselib.h (fp_setter_insn): New prototype.
|
||||
* cselib.c (fp_setter_insn): New function.
|
||||
(cselib_process_insn): If frame_pointer_needed,
|
||||
call cselib_invalidate_rtx (stack_pointer_rtx) after
|
||||
processing a frame pointer setter.
|
||||
* var-tracking.c (fp_setter): Removed.
|
||||
(vt_initialize): Use fp_setter_insn instead of fp_setter.
|
||||
|
||||
2012-11-19 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
* config/rs6000/rs6000.md (movdf_hardfloat32): Reorder move
|
||||
|
30
gcc/cselib.c
30
gcc/cselib.c
@ -2593,6 +2593,28 @@ cselib_record_sets (rtx insn)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if INSN in the prologue initializes hard_frame_pointer_rtx. */
|
||||
|
||||
bool
|
||||
fp_setter_insn (rtx insn)
|
||||
{
|
||||
rtx expr, pat = NULL_RTX;
|
||||
|
||||
if (!RTX_FRAME_RELATED_P (insn))
|
||||
return false;
|
||||
|
||||
expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
|
||||
if (expr)
|
||||
pat = XEXP (expr, 0);
|
||||
if (!modified_in_p (hard_frame_pointer_rtx, pat ? pat : insn))
|
||||
return false;
|
||||
|
||||
/* Don't return true for frame pointer restores in the epilogue. */
|
||||
if (find_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Record the effects of INSN. */
|
||||
|
||||
void
|
||||
@ -2651,6 +2673,14 @@ cselib_process_insn (rtx insn)
|
||||
if (GET_CODE (XEXP (x, 0)) == CLOBBER)
|
||||
cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0));
|
||||
|
||||
/* On setter of the hard frame pointer if frame_pointer_needed,
|
||||
invalidate stack_pointer_rtx, so that sp and {,h}fp based
|
||||
VALUEs are distinct. */
|
||||
if (reload_completed
|
||||
&& frame_pointer_needed
|
||||
&& fp_setter_insn (insn))
|
||||
cselib_invalidate_rtx (stack_pointer_rtx);
|
||||
|
||||
cselib_current_insn = NULL_RTX;
|
||||
|
||||
if (n_useless_values > MAX_USELESS_VALUES
|
||||
|
@ -78,6 +78,7 @@ extern void cselib_init (int);
|
||||
extern void cselib_clear_table (void);
|
||||
extern void cselib_finish (void);
|
||||
extern void cselib_process_insn (rtx);
|
||||
extern bool fp_setter_insn (rtx);
|
||||
extern enum machine_mode cselib_reg_set_mode (const_rtx);
|
||||
extern int rtx_equal_for_cselib_p (rtx, rtx);
|
||||
extern int references_value_p (const_rtx, int);
|
||||
|
@ -1,3 +1,8 @@
|
||||
2012-11-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/54921
|
||||
* gcc.dg/pr54921.c: New test.
|
||||
|
||||
2012-11-19 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* gcc.target/i386/pr55359.c: New test.
|
||||
|
32
gcc/testsuite/gcc.dg/pr54921.c
Normal file
32
gcc/testsuite/gcc.dg/pr54921.c
Normal file
@ -0,0 +1,32 @@
|
||||
/* PR rtl-optimization/54921 */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-Os -fno-omit-frame-pointer -fsched2-use-superblocks -ftree-slp-vectorize" } */
|
||||
/* { dg-additional-options "-fstack-protector" { target fstack_protector } } */
|
||||
|
||||
struct A
|
||||
{
|
||||
int a;
|
||||
char b[32];
|
||||
} a, b;
|
||||
|
||||
__attribute__((noinline, noclone))
|
||||
struct A
|
||||
bar (int x)
|
||||
{
|
||||
struct A r;
|
||||
static int n;
|
||||
r.a = ++n;
|
||||
__builtin_memset (r.b, 0, sizeof (r.b));
|
||||
r.b[0] = x;
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
a = bar (3);
|
||||
b = bar (4);
|
||||
if (a.a != 1 || a.b[0] != 3 || b.a != 2 || b.b[0] != 4)
|
||||
__builtin_abort ();
|
||||
return 0;
|
||||
}
|
@ -9522,40 +9522,6 @@ vt_add_function_parameters (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if INSN in the prologue initializes hard_frame_pointer_rtx. */
|
||||
|
||||
static bool
|
||||
fp_setter (rtx insn)
|
||||
{
|
||||
rtx pat = PATTERN (insn);
|
||||
if (RTX_FRAME_RELATED_P (insn))
|
||||
{
|
||||
rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
|
||||
if (expr)
|
||||
pat = XEXP (expr, 0);
|
||||
}
|
||||
if (GET_CODE (pat) == SET)
|
||||
{
|
||||
if (SET_DEST (pat) != hard_frame_pointer_rtx)
|
||||
return false;
|
||||
}
|
||||
else if (GET_CODE (pat) == PARALLEL)
|
||||
{
|
||||
int i;
|
||||
for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
|
||||
if (GET_CODE (XVECEXP (pat, 0, i)) == SET
|
||||
&& SET_DEST (XVECEXP (pat, 0, i)) == hard_frame_pointer_rtx)
|
||||
break;
|
||||
if (i < 0)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
if (find_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Initialize cfa_base_rtx, create a preserved VALUE for it and
|
||||
ensure it isn't flushed during cselib_reset_table.
|
||||
Can be called only if frame_pointer_rtx resp. arg_pointer_rtx
|
||||
@ -9859,8 +9825,7 @@ vt_initialize (void)
|
||||
|
||||
if (fp_cfa_offset != -1
|
||||
&& hard_frame_pointer_adjustment == -1
|
||||
&& RTX_FRAME_RELATED_P (insn)
|
||||
&& fp_setter (insn))
|
||||
&& fp_setter_insn (insn))
|
||||
{
|
||||
vt_init_cfa_base ();
|
||||
hard_frame_pointer_adjustment = fp_cfa_offset;
|
||||
|
Loading…
Reference in New Issue
Block a user