This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix find_call_stack_args in RTL DCE (PR rtl-optimization/47337, take 2)


On Wed, Jan 19, 2011 at 01:36:49AM +0100, Eric Botcazou wrote:
> > 2011-01-18  Jakub Jelinek  <jakub@redhat.com>
> >
> > 	PR rtl-optimization/47337
> > 	* dce.c (find_call_stack_args): Ignore debug insns.
> > 	Stop on memory stores other than argument stores.
> 
> Can you make an (inline) predicate out of the test and just do:
> 
>   if (predicate (xxx))
>     break;
> 
> instead?

So like this?

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.

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

--- gcc/dce.c.jj	2011-01-18 23:56:46.713420010 +0100
+++ gcc/dce.c	2011-01-19 09:51:15.756808297 +0100
@@ -220,6 +220,26 @@ mark_nonreg_stores (rtx body, rtx insn, 
 }
 
 
+/* 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, boo
   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, boo
       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, boo
 	    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;
 
--- gcc/testsuite/gcc.c-torture/execute/pr47337.c.jj	2011-01-19 09:38:08.747806904 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr47337.c	2011-01-19 09:38:08.747806904 +0100
@@ -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;
+}


	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]