PR rtl-optimization/34628
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 22 Jan 2008 22:27:47 +0000 (22:27 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 22 Jan 2008 22:27:47 +0000 (22:27 +0000)
* combine.c (try_combine): Stop and undo after the first combination
if an autoincrement side-effect on the first insn has effectively
been lost.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@131744 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20080122-1.c [new file with mode: 0644]

index f882548..b59acd5 100644 (file)
@@ -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
index 43623a4..5cfa305 100644 (file)
@@ -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;
index 255201a..4ae4df9 100644 (file)
@@ -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 (file)
index 0000000..a2f7fed
--- /dev/null
@@ -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;
+}