diff options
author | Jakub Jelinek <jakub@redhat.com> | 2012-11-20 09:34:43 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2012-11-20 09:34:43 +0100 |
commit | 40155239d684ae96712d34f3f4dcc88eef4fc99d (patch) | |
tree | b8e399f48378d1d27ec4ce799592476990e6187c /gcc/cselib.c | |
parent | 4ced1d6de8b7ad914c4ea6fdb3121487d298c9e0 (diff) | |
download | gcc-40155239d684ae96712d34f3f4dcc88eef4fc99d.zip gcc-40155239d684ae96712d34f3f4dcc88eef4fc99d.tar.gz gcc-40155239d684ae96712d34f3f4dcc88eef4fc99d.tar.bz2 |
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
Diffstat (limited to 'gcc/cselib.c')
-rw-r--r-- | gcc/cselib.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/gcc/cselib.c b/gcc/cselib.c index 92193ba..28f8d07 100644 --- a/gcc/cselib.c +++ b/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 |