summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2005-12-21 15:28:16 +0000
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2005-12-21 15:28:16 +0000
commit5630a23e0a4e483c8c405a32782d01f4b64f6654 (patch)
tree4f288befddb9d14189f3a940fb389582659ff8ec
parent2226345888ecbe934332f522097ad22c407e2efc (diff)
downloadgcc-5630a23e0a4e483c8c405a32782d01f4b64f6654.tar.gz
patch for PR rtl-optimization/25130
gcc/ * postreload-gcse.c (record_last_set_info): Notice stack pointer changes in push insns without REG_INC notes. testsuite/ * gcc.dg/pr25130.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@108906 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/postreload-gcse.c16
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr25130.c34
4 files changed, 57 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7c34089a752..2db3153e910 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-12-21 Steven Bosscher <stevenb@suse.de>
+
+ PR rtl-optimization/25130
+ * postreload-gcse.c (record_last_set_info): Notice stack pointer
+ changes in push insns without REG_INC notes.
+
2005-12-21 Kazu Hirata <kazu@codesourcery.com>
PR tree-optimization/25382.
diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c
index 191d7965eeb..4fc66ec4ee6 100644
--- a/gcc/postreload-gcse.c
+++ b/gcc/postreload-gcse.c
@@ -671,10 +671,18 @@ record_last_set_info (rtx dest, rtx setter ATTRIBUTE_UNUSED, void *data)
if (REG_P (dest))
record_last_reg_set_info (last_set_insn, REGNO (dest));
- else if (MEM_P (dest)
- /* Ignore pushes, they clobber nothing. */
- && ! push_operand (dest, GET_MODE (dest)))
- record_last_mem_set_info (last_set_insn);
+ else if (MEM_P (dest))
+ {
+ /* Ignore pushes, they don't clobber memory. They may still
+ clobber the stack pointer though. Some targets do argument
+ pushes without adding REG_INC notes. See e.g. PR25196,
+ where a pushsi2 on i386 doesn't have REG_INC notes. Note
+ such changes here too. */
+ if (! push_operand (dest, GET_MODE (dest)))
+ record_last_mem_set_info (last_set_insn);
+ else
+ record_last_reg_set_info (last_set_insn, STACK_POINTER_REGNUM);
+ }
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2899ab208b9..fb9dd4898e1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-12-21 Steven Bosscher <stevenb@suse.de>
+
+ PR rtl-optimization/25130
+ * gcc.dg/pr25130.c: New test.
+
2005-12-21 Erik Edelmann <eedelman@gcc.gnu.org>
PR fortran/25423
diff --git a/gcc/testsuite/gcc.dg/pr25130.c b/gcc/testsuite/gcc.dg/pr25130.c
new file mode 100644
index 00000000000..e73faffe721
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr25130.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-march=i386 -O3 -fomit-frame-pointer" } */
+
+/* For this test case, we used to do an invalid load motion after
+ reload, because we missed autoincrements of the stack pointer. */
+
+extern void abort (void);
+
+static int j;
+
+static void __attribute__((noinline))
+f1 (int a, int b, int c, int d, int e)
+{
+ j = a;
+}
+
+int __attribute__((noinline))
+f2 (int a, int b, int c, int d, int e)
+{
+ if ((b & 0x1111) != 1)
+ f1 (a, b, c, d, e);
+ return 0;
+}
+
+int
+main (void)
+{
+ f2 (123, 0, 0, 0, 0);
+ if (j != 123)
+ abort ();
+ return 0;
+}
+