diff mbox

Fix cprop ICE with conditional asserts becoming non-conditional (PR rtl-optimization/79386)

Message ID 20170206194133.GP1849@tucnak
State New
Headers show

Commit Message

Jakub Jelinek Feb. 6, 2017, 7:41 p.m. UTC
Hi!

The recent r244993 change where bypass_conditional_jumps is called only
after splitting blocks for unconditional traps can result in ICEs during
bypass_conditional_jumps, because on the (unreachable, to be removed later)
new basic blocks created by that splitting we don't have cprop per-bb data
structures like cprop_avout computed (nor space for them allocated).
bypass_conditional_jumps already uses bypass_last_basic_block variable
to avoid touching basic blocks created during that function, so this
patch just extends that to also the basic blocks created for splitting
after unconditional traps.

Bootstrapped/regtested on {x86_64,i686,powerpc64{,le}}-linux, ok for trunk?

2017-02-06  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/79386
	* cprop.c (bypass_conditional_jumps): Initialize
	bypass_last_basic_block already before splitting bbs after
	unconditional traps...
	(bypass_conditional_jumps): ... rather than here.

	* gcc.c-torture/compile/pr79386.c: New test.


	Jakub

Comments

Jeff Law Feb. 7, 2017, 5:43 p.m. UTC | #1
On 02/06/2017 12:41 PM, Jakub Jelinek wrote:
> Hi!
>
> The recent r244993 change where bypass_conditional_jumps is called only
> after splitting blocks for unconditional traps can result in ICEs during
> bypass_conditional_jumps, because on the (unreachable, to be removed later)
> new basic blocks created by that splitting we don't have cprop per-bb data
> structures like cprop_avout computed (nor space for them allocated).
> bypass_conditional_jumps already uses bypass_last_basic_block variable
> to avoid touching basic blocks created during that function, so this
> patch just extends that to also the basic blocks created for splitting
> after unconditional traps.
>
> Bootstrapped/regtested on {x86_64,i686,powerpc64{,le}}-linux, ok for trunk?
>
> 2017-02-06  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR rtl-optimization/79386
> 	* cprop.c (bypass_conditional_jumps): Initialize
> 	bypass_last_basic_block already before splitting bbs after
> 	unconditional traps...
> 	(bypass_conditional_jumps): ... rather than here.
>
> 	* gcc.c-torture/compile/pr79386.c: New test.
OK.

jeff
diff mbox

Patch

--- gcc/cprop.c.jj	2017-01-30 09:31:48.000000000 +0100
+++ gcc/cprop.c	2017-02-06 14:37:07.157093577 +0100
@@ -1697,7 +1697,6 @@  bypass_conditional_jumps (void)
   if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
     return 0;
 
-  bypass_last_basic_block = last_basic_block_for_fn (cfun);
   mark_dfs_back_edges ();
 
   changed = 0;
@@ -1863,6 +1862,11 @@  one_cprop_pass (void)
 	      }
 	}
 
+      /* Make sure bypass_conditional_jumps will ignore not just its new
+	 basic blocks, but also the ones after unconditional traps (those are
+	 unreachable and will be eventually removed as such).  */
+      bypass_last_basic_block = last_basic_block_for_fn (cfun);
+
       while (!uncond_traps.is_empty ())
 	{
 	  rtx_insn *insn = uncond_traps.pop ();
--- gcc/testsuite/gcc.c-torture/compile/pr79386.c.jj	2017-02-06 14:43:31.932063697 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr79386.c	2017-02-06 14:43:19.000000000 +0100
@@ -0,0 +1,46 @@ 
+/* PR rtl-optimization/79386 */
+
+int a, b;
+
+int
+foo (int x)
+{
+  int c;
+  int *d, *e;
+
+  if (b == 0)
+    {
+      c = 0;
+      e = &b;
+      d = &b;
+    }
+  else
+    {
+      int f;
+
+      c = 1;
+      for (f = 0; f < 9; ++f)
+	c *= 3;
+      e = (int *) (__UINTPTR_TYPE__) c;
+      d = &x;
+    }
+  *e = c < 3;
+  if (*e != 0)
+    {
+      int g;
+
+      b += (a != 0) ? a : 1;
+      if (g != 0 || x != 0)
+	*d = 0;
+      if (b >= 0)
+	{
+	  if (g != 0)
+	    g = x;
+	  if (*d / g != 0)
+	    for (;;)
+	      ;
+	}
+    }
+
+  return b * (a != 0 && *d != 0);
+}