diff mbox

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

Message ID 20110118225458.GK2724@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Jan. 18, 2011, 10:54 p.m. UTC
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.


	Jakub

Comments

Eric Botcazou Jan. 19, 2011, 12:36 a.m. UTC | #1
> 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?

This affects more than the trunk, right?

> 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?
Jakub Jelinek Jan. 19, 2011, 12:44 a.m. UTC | #2
On Wed, Jan 19, 2011 at 01:36:49AM +0100, Eric Botcazou wrote:
> > 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?
> 
> This affects more than the trunk, right?

Yeah, 4.4+, I'd backport it after a while.

> > 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?

Well, it isn't just a predicate because it also clears bits in the sp_bits
bitmap, and would need 5 arguments, but yeah, it could be turned into an
static inline.

	Jakub
diff mbox

Patch

--- 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;
+}