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

Jakub Jelinek jakub@redhat.com
Wed Jan 19 00:44:00 GMT 2011


Hi!

I've made a thinko in this routine, the break; out of the for loop
iterating over each byte in the MEM was meant to break out of the outer
loop, but only terminated the inner loop, thus if some unrelated sp related
memory store was moved after some stack argument store, RTL DCE would
happily delete it together with the call if it is being DCEd.

Fixed thusly.  Also I've fixed a potential -fcompare-debug issue,
DEBUG_INSNs should be ignored here rather than make the call non-DCEable.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

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.

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

--- gcc/dce.c.jj	2011-01-03 19:22:53.000000000 +0100
+++ gcc/dce.c	2011-01-18 10:37:12.590320188 +0100
@@ -374,7 +374,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);
@@ -444,6 +444,9 @@ find_call_stack_args (rtx call_insn, boo
 	    break;
 	}
 
+      if (byte < off + GET_MODE_SIZE (GET_MODE (mem)))
+	break;
+
       if (!deletable_insn_p (insn, fast, NULL))
 	break;
 
--- gcc/testsuite/gcc.c-torture/execute/pr47337.c.jj	2011-01-18 10:51:43.539389291 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr47337.c	2011-01-18 10:51:16.000000000 +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



More information about the Gcc-patches mailing list