diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-05-01 11:50:59 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-05-01 11:50:59 +0200 |
commit | 30776a1468d25d156c02b2484d5ad7578f829d2e (patch) | |
tree | 8b474243cad264fb5c3c25797a360bfb208f12b8 | |
parent | f16b9dc289af11bc64e8ae27a6723f2f82ca2cc5 (diff) | |
download | gcc-30776a1468d25d156c02b2484d5ad7578f829d2e.zip gcc-30776a1468d25d156c02b2484d5ad7578f829d2e.tar.gz gcc-30776a1468d25d156c02b2484d5ad7578f829d2e.tar.bz2 |
re PR target/79430 (action of statement incorrectly optimised away)
PR target/79430
* rtlanal.c (reg_set_p): If reg is a stack_pointer_rtx, also
check for stack push/pop autoinc.
* config/i386/i386.c (ix86_agi_dependent): Return false
if the only reason why modified_in_p returned true is that
addr is SP based and set_insn is a push or pop.
From-SVN: r247429
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 21 | ||||
-rw-r--r-- | gcc/rtlanal.c | 18 |
3 files changed, 47 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f8bde7a..52c6a4e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2017-05-01 Jakub Jelinek <jakub@redhat.com> + + PR target/79430 + * rtlanal.c (reg_set_p): If reg is a stack_pointer_rtx, also + check for stack push/pop autoinc. + * config/i386/i386.c (ix86_agi_dependent): Return false + if the only reason why modified_in_p returned true is that + addr is SP based and set_insn is a push or pop. + 2017-04-29 Jan Hubicka <hubicka@ucw.cz> PR ipa/79224 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index d985657..a09c2c7 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -29243,7 +29243,26 @@ ix86_agi_dependent (rtx_insn *set_insn, rtx_insn *use_insn) if (MEM_P (recog_data.operand[i])) { rtx addr = XEXP (recog_data.operand[i], 0); - return modified_in_p (addr, set_insn) != 0; + if (modified_in_p (addr, set_insn) != 0) + { + /* No AGI stall if SET_INSN is a push or pop and USE_INSN + has SP based memory (unless index reg is modified in a pop). */ + rtx set = single_set (set_insn); + if (set + && (push_operand (SET_DEST (set), GET_MODE (SET_DEST (set))) + || pop_operand (SET_SRC (set), GET_MODE (SET_SRC (set))))) + { + struct ix86_address parts; + if (ix86_decompose_address (addr, &parts) + && parts.base == stack_pointer_rtx + && (parts.index == NULL_RTX + || MEM_P (SET_DEST (set)) + || !modified_in_p (parts.index, set_insn))) + return false; + } + return true; + } + return false; } return false; } diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index acb4230..321363f 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -1221,6 +1221,24 @@ reg_set_p (const_rtx reg, const_rtx insn) || find_reg_fusage (insn, CLOBBER, reg))))) return true; + /* There are no REG_INC notes for SP autoinc. */ + if (reg == stack_pointer_rtx && INSN_P (insn)) + { + subrtx_var_iterator::array_type array; + FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), NONCONST) + { + rtx mem = *iter; + if (mem + && MEM_P (mem) + && GET_RTX_CLASS (GET_CODE (XEXP (mem, 0))) == RTX_AUTOINC) + { + if (XEXP (XEXP (mem, 0), 0) == stack_pointer_rtx) + return true; + iter.skip_subrtxes (); + } + } + } + return set_of (reg, insn) != NULL_RTX; } |