aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-05-01 11:50:59 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2017-05-01 11:50:59 +0200
commit30776a1468d25d156c02b2484d5ad7578f829d2e (patch)
tree8b474243cad264fb5c3c25797a360bfb208f12b8
parentf16b9dc289af11bc64e8ae27a6723f2f82ca2cc5 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/config/i386/i386.c21
-rw-r--r--gcc/rtlanal.c18
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;
}