aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2008-01-22 22:27:47 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2008-01-22 22:27:47 +0000
commitdf1a98aecad77169b4c7dcad9b3bab7c5d9f1f24 (patch)
treef6cd942ff09ad36a0c1afc80f243cd5ceb433923 /gcc
parentec46053bfa418579cf557fa34b140ddd25f1717b (diff)
downloadgcc-df1a98aecad77169b4c7dcad9b3bab7c5d9f1f24.zip
gcc-df1a98aecad77169b4c7dcad9b3bab7c5d9f1f24.tar.gz
gcc-df1a98aecad77169b4c7dcad9b3bab7c5d9f1f24.tar.bz2
re PR rtl-optimization/34628 (problems with inlining on ARM)
PR rtl-optimization/34628 * combine.c (try_combine): Stop and undo after the first combination if an autoincrement side-effect on the first insn has effectively been lost. From-SVN: r131744
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/combine.c17
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20080122-1.c35
4 files changed, 57 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f882548..b59acd5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2008-01-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR rtl-optimization/34628
+ * combine.c (try_combine): Stop and undo after the first combination
+ if an autoincrement side-effect on the first insn has effectively
+ been lost.
+
2008-01-22 David Edelsohn <edelsohn@gnu.org>
PR target/34529
diff --git a/gcc/combine.c b/gcc/combine.c
index 43623a4..5cfa305 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -2751,12 +2751,17 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
if (i1 && GET_CODE (newpat) != CLOBBER)
{
- /* Before we can do this substitution, we must redo the test done
- above (see detailed comments there) that ensures that I1DEST
- isn't mentioned in any SETs in NEWPAT that are field assignments. */
-
- if (! combinable_i3pat (NULL_RTX, &newpat, i1dest, NULL_RTX,
- 0, (rtx*) 0))
+ /* Check that an autoincrement side-effect on I1 has not been lost.
+ This happens if I1DEST is mentioned in I2 and dies there, and
+ has disappeared from the new pattern. */
+ if ((FIND_REG_INC_NOTE (i1, NULL_RTX) != 0
+ && !i1_feeds_i3
+ && dead_or_set_p (i2, i1dest)
+ && !reg_overlap_mentioned_p (i1dest, newpat))
+ /* Before we can do this substitution, we must redo the test done
+ above (see detailed comments there) that ensures that I1DEST
+ isn't mentioned in any SETs in NEWPAT that are field assignments. */
+ || !combinable_i3pat (NULL_RTX, &newpat, i1dest, NULL_RTX, 0, 0))
{
undo_all ();
return 0;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 255201a..4ae4df9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2008-01-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.c-torture/execute/20080122-1.c: New test.
+
2008-01-22 Tom Tromey <tromey@redhat.com>
PR c++/34859:
diff --git a/gcc/testsuite/gcc.c-torture/execute/20080122-1.c b/gcc/testsuite/gcc.c-torture/execute/20080122-1.c
new file mode 100644
index 0000000..a2f7fed
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20080122-1.c
@@ -0,0 +1,35 @@
+/* PR rtl-optimization/34628 */
+/* Origin: Martin Michlmayr <tbm@cyrius.com> */
+
+typedef unsigned short u16;
+typedef unsigned char u8;
+
+static void
+do_segfault(u8 in_buf[], const u8 out_buf[], const int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ asm("");
+
+ in_buf[2*i] = ( out_buf[2*i] | out_buf[(2*i)+1]<<8 ) & 0xFF;
+
+ asm("");
+
+ in_buf[(2*i)+1] = ( out_buf[2*i] | out_buf[(2*i)+1]<<8 ) >> 8;
+
+ asm("");
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ u8 outbuf[32] = "buffer ";
+ u8 inbuf[32] = "\f";
+
+ asm("");
+ do_segfault(inbuf, outbuf, 12);
+ asm("");
+
+ return 0;
+}