[PATCH] Fix PR56350

Richard Biener rguenther@suse.de
Mon Feb 18 10:39:00 GMT 2013


The issue in PR56350 is two-fold.  First, fix_loop_structure mishandles
latch edge computation (ugh).  Second, RTL if-conversion, when merging
a latch block into sth else ends up generating stale latch block
references.

The following two patches cure that, adding some basic latch block
checking.

Bootstrap & regtest running on x86_64-unknown-linux-gnu.

Richard.

2013-02-18  Richard Biener  <rguenther@suse.de>

	PR middle-end/56349
	* cfgloop.c (flow_loops_find): Reset latch before recomputing it.
	(verify_loop_structure): Verify that a recorded latch is in fact
	a latch.

Index: gcc/cfgloop.c
===================================================================
*** gcc/cfgloop.c	(revision 196115)
--- gcc/cfgloop.c	(working copy)
*************** flow_loops_find (struct loops *loops)
*** 466,471 ****
--- 466,473 ----
  			 "loop %d with header %d\n",
  			 loop->num, header->index);
  	    }
+ 	  /* Reset latch, we recompute it below.  */
+ 	  loop->latch = NULL;
  	  larray.safe_push (loop);
  	}
  
*************** verify_loop_structure (void)
*** 1413,1418 ****
--- 1415,1433 ----
  	  error ("loop %d%'s header does not have exactly 2 entries", i);
  	  err = 1;
  	}
+       if (loop->latch)
+ 	{
+ 	  if (!find_edge (loop->latch, loop->header))
+ 	    {
+ 	      error ("loop %d%'s latch does not have an edge to its header", i);
+ 	      err = 1;
+ 	    }
+ 	  if (!dominated_by_p (CDI_DOMINATORS, loop->latch, loop->header))
+ 	    {
+ 	      error ("loop %d%'s latch is not dominated by its header", i);
+ 	      err = 1;
+ 	    }
+ 	}
        if (loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES))
  	{
  	  if (!single_succ_p (loop->latch))


2013-02-18  Richard Biener  <rguenther@suse.de>

	PR middle-end/56350
	* cfghooks.c (merge_blocks): If we merge a latch into another
	block adjust references to it.

	* gcc.dg/torture/pr56350.c: New testcase.

Index: gcc/cfghooks.c
===================================================================
*** gcc/cfghooks.c	(revision 196115)
--- gcc/cfghooks.c	(working copy)
*************** merge_blocks (basic_block a, basic_block
*** 761,767 ****
      {
        e->src = a;
        if (current_loops != NULL)
! 	rescan_loop_exit (e, true, false);
      }
    a->succs = b->succs;
    a->flags |= b->flags;
--- 761,772 ----
      {
        e->src = a;
        if (current_loops != NULL)
! 	{
! 	  /* If b was a latch, a now is.  */
! 	  if (e->dest->loop_father->latch == b)
! 	    e->dest->loop_father->latch = a;
! 	  rescan_loop_exit (e, true, false);
! 	}
      }
    a->succs = b->succs;
    a->flags |= b->flags;
Index: gcc/testsuite/gcc.dg/torture/pr56350.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr56350.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr56350.c	(working copy)
***************
*** 0 ****
--- 1,41 ----
+ /* { dg-do compile } */
+ 
+ int a, b;
+ short c;
+ 
+ void f(void)
+ {
+   int a = 0;
+   int *k = 0;
+ 
+   for(; a < 2; a++);
+ 
+   if(!!(b |= a < 3) - 1)
+     {
+       if(0)
+ 	for (;; a++)
+ 	  {
+ 	    for (; c; *k = 0);
+ lbl1:
+ 	    ;
+ 	  }
+ 
+       for(; *k; k++)
+ 	{
+ 	  c = b ? : a;
+ 
+ 	  if (c)
+ 	    lbl2:
+ 		b = 0;
+ 	}
+       goto lbl1;
+     }
+ 
+   for(;; b++)
+     {
+       if(b)
+ 	goto lbl2;
+ 
+       k = &b;
+     }
+ }



More information about the Gcc-patches mailing list