re PR rtl-optimization/47337 (Wrong RTL dce of calls)
authorJakub Jelinek <jakub@redhat.com>
Wed, 19 Jan 2011 15:13:01 +0000 (16:13 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 19 Jan 2011 15:13:01 +0000 (16:13 +0100)
PR rtl-optimization/47337
* dce.c (check_argument_store): New function.
(find_call_stack_args): Ignore debug insns.  Use check_argument_store.

* gcc.c-torture/execute/pr47337.c: New test.

From-SVN: r168997

gcc/ChangeLog
gcc/dce.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr47337.c [new file with mode: 0644]

index c456fb34f5bd34ef4feaf863d40813243e0db9f1..b799162f70bfe112a1e11aa786a4ed7e03251e94 100644 (file)
@@ -1,5 +1,9 @@
 2011-01-19  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/47337
+       * dce.c (check_argument_store): New function.
+       (find_call_stack_args): Ignore debug insns.  Use check_argument_store.
+
        PR tree-optimization/47290
        * tree-eh.c (infinite_empty_loop_p): New function.
        (cleanup_empty_eh): Use it.
index e6e9836500595507043d3ab1dd26ab707bd49ff6..f63d09e4164286f8bc52c0b5ca048f599f843744 100644 (file)
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -1,5 +1,5 @@
 /* RTL dead code elimination.
-   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -220,6 +220,26 @@ mark_nonreg_stores (rtx body, rtx insn, bool fast)
 }
 
 
+/* Return true if store to MEM, starting OFF bytes from stack pointer,
+   is a call argument store, and clear corresponding bits from SP_BYTES
+   bitmap if it is.  */
+
+static bool
+check_argument_store (rtx mem, HOST_WIDE_INT off, HOST_WIDE_INT min_sp_off,
+                     HOST_WIDE_INT max_sp_off, bitmap sp_bytes)
+{
+  HOST_WIDE_INT byte;
+  for (byte = off; byte < off + GET_MODE_SIZE (GET_MODE (mem)); byte++)
+    {
+      if (byte < min_sp_off
+         || byte >= max_sp_off
+         || !bitmap_clear_bit (sp_bytes, byte - min_sp_off))
+       return false;
+    }
+  return true;
+}
+
+
 /* Try to find all stack stores of CALL_INSN arguments if
    ACCUMULATE_OUTGOING_ARGS.  If all stack stores have been found
    and it is therefore safe to eliminate the call, return true,
@@ -364,7 +384,7 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast,
   for (insn = PREV_INSN (call_insn); insn; insn = prev_insn)
     {
       rtx set, mem, addr;
-      HOST_WIDE_INT off, byte;
+      HOST_WIDE_INT off;
 
       if (insn == BB_HEAD (BLOCK_FOR_INSN (call_insn)))
        prev_insn = NULL_RTX;
@@ -374,7 +394,7 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast,
       if (CALL_P (insn))
        break;
 
-      if (!INSN_P (insn))
+      if (!NONDEBUG_INSN_P (insn))
        continue;
 
       set = single_set (insn);
@@ -433,17 +453,11 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast,
            break;
        }
 
-      if (GET_MODE_SIZE (GET_MODE (mem)) == 0)
+      if (GET_MODE_SIZE (GET_MODE (mem)) == 0
+         || !check_argument_store (mem, off, min_sp_off,
+                                   max_sp_off, sp_bytes))
        break;
 
-      for (byte = off; byte < off + GET_MODE_SIZE (GET_MODE (mem)); byte++)
-       {
-         if (byte < min_sp_off
-             || byte >= max_sp_off
-             || !bitmap_clear_bit (sp_bytes, byte - min_sp_off))
-           break;
-       }
-
       if (!deletable_insn_p (insn, fast, NULL))
        break;
 
index 3e60bc320cda3cbb7188bde50e8343979fa41156..ef62c3c9b02f7e509a928f54c8f64a75ef6ef561 100644 (file)
@@ -1,3 +1,8 @@
+2011-01-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/47337
+       * gcc.c-torture/execute/pr47337.c: New test.
+
 2011-01-19  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
 
        PR testsuite/45342
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr47337.c b/gcc/testsuite/gcc.c-torture/execute/pr47337.c
new file mode 100644 (file)
index 0000000..ea88484
--- /dev/null
@@ -0,0 +1,86 @@
+/* PR rtl-optimization/47337 */
+
+static unsigned int a[256], b = 0;
+static char c = 0;
+static int d = 0, *f = &d;
+static long long e = 0;
+
+static short
+foo (long long x, long long y)
+{
+  return x / y;
+}
+
+static char
+bar (char x, char y)
+{
+  return x - y;
+}
+
+static int
+baz (int x, int y)
+{
+  *f = (y != (short) (y * 3));
+  for (c = 0; c < 2; c++)
+    {
+    lab:
+      if (d)
+       {
+         if (e)
+           e = 1;
+         else
+           return x;
+       }
+      else
+       {
+         d = 1;
+         goto lab;
+       }
+      f = &d;
+    }
+  return x;
+}
+
+static void
+fnx (unsigned long long x, int y)
+{
+  if (!y)
+    {
+      b = a[b & 1];
+      b = a[b & 1];
+      b = a[(b ^ (x & 1)) & 1];
+      b = a[(b ^ (x & 1)) & 1];
+    }
+}
+
+char *volatile w = "2";
+
+int
+main ()
+{
+  int h = 0;
+  unsigned int k = 0;
+  int l[8];
+  int i, j;
+
+  if (__builtin_strcmp (w, "1") == 0)
+    h = 1;
+
+  for (i = 0; i < 256; i++)
+    {
+      for (j = 8; j > 0; j--)
+       k = 1;
+      a[i] = k;
+    }
+  for (i = 0; i < 8; i++)
+    l[i] = 0;
+
+  d = bar (c, c);
+  d = baz (c, 1 | foo (l[0], 10));
+  fnx (d, h);
+  fnx (e, h);
+
+  if (d != 0)
+    __builtin_abort ();
+  return 0;
+}