[PATCH] Fix undefined label problem after crossjumping (PR rtl-optimization/64536)

Richard Biener rguenther@suse.de
Fri Jan 9 14:21:00 GMT 2015


On Fri, 9 Jan 2015, Jakub Jelinek wrote:

> On Fri, Jan 09, 2015 at 11:59:44AM +0100, Richard Biener wrote:
> > > If you want, I can try instead of disabling it for tablejumps
> > > just move the label.
> > 
> > Yeah, I'd prefer that - it can't be too difficult, no?
> 
> So like this (tested just on the testcase, fully bootstrap/regtest
> will follow)?

Yeah.

> > > Still, I think we should be able to optimize it somewhere else too 
> > > (we can remove the tablejumps not just if all jump_table_data 
> > > entries point to next_bb, but even when they point to some 
> > > completely different bb, as long as it is a single_succ_p).  And 
> > > ideally also optimize it at GIMPLE, but guess that is GCC 6 
> > > material.
> > 
> > cfgcleanup material, similar for GIMPLE I guess.
> 
> You mean that cfgcleanup changes are GCC 6 material too?

Well, you have until the end of next week ;)  For GIMPLE this is
a switch with all cases going to the same basic-block, right?
I think we optimize that in cleanup_control_expr_graph via the
single_succ_p case?

Thanks,
Richard.

> 2015-01-09  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR rtl-optimization/64536
> 	* cfgrtl.c (rtl_tidy_fallthru_edge): Handle removal of degenerate
> 	tablejumps.
> 
> 	* gcc.dg/pr64536.c: New test.
> 
> --- gcc/cfgrtl.c.jj	2015-01-08 18:10:23.616598916 +0100
> +++ gcc/cfgrtl.c	2015-01-09 14:47:26.637855477 +0100
> @@ -1791,6 +1791,24 @@ rtl_tidy_fallthru_edge (edge e)
>        && (any_uncondjump_p (q)
>  	  || single_succ_p (b)))
>      {
> +      rtx label;
> +      rtx_jump_table_data *table;
> +
> +      if (tablejump_p (q, &label, &table))
> +	{
> +	  /* The label is likely mentioned in some instruction before
> +	     the tablejump and might not be DCEd, so turn it into
> +	     a note instead and move before the tablejump that is going to
> +	     be deleted.  */
> +	  const char *name = LABEL_NAME (label);
> +	  PUT_CODE (label, NOTE);
> +	  NOTE_KIND (label) = NOTE_INSN_DELETED_LABEL;
> +	  NOTE_DELETED_LABEL_NAME (label) = name;
> +	  rtx_insn *lab = safe_as_a <rtx_insn *> (label);
> +	  reorder_insns (lab, lab, PREV_INSN (q));
> +	  delete_insn (table);
> +	}
> +
>  #ifdef HAVE_cc0
>        /* If this was a conditional jump, we need to also delete
>  	 the insn that set cc0.  */
> --- gcc/testsuite/gcc.dg/pr64536.c.jj	2015-01-09 13:55:53.035267213 +0100
> +++ gcc/testsuite/gcc.dg/pr64536.c	2015-01-09 13:55:53.035267213 +0100
> @@ -0,0 +1,67 @@
> +/* PR rtl-optimization/64536 */
> +/* { dg-do link } */
> +/* { dg-options "-O2" } */
> +/* { dg-additional-options "-fPIC" { target fpic } } */
> +
> +struct S { long q; } *h;
> +long a, b, g, j, k, *c, *d, *e, *f, *i;
> +long *baz (void)
> +{
> +  asm volatile ("" : : : "memory");
> +  return e;
> +}
> +
> +void
> +bar (int x)
> +{
> +  int y;
> +  for (y = 0; y < x; y++)
> +    {
> +      switch (b)
> +	{
> +	case 0:
> +	case 2:
> +	  a++;
> +	  break;
> +	case 3:
> +	  a++;
> +	  break;
> +	case 1:
> +	  a++;
> +	}
> +      if (d)
> +	{
> +	  f = baz ();
> +	  g = k++;
> +	  if (&h->q)
> +	    {
> +	      j = *f;
> +	      h->q = *f;
> +	    }
> +	  else
> +	    i = (long *) (h->q = *f);
> +	  *c++ = (long) f;
> +	  e += 6;
> +	}
> +      else
> +	{
> +	  f = baz ();
> +	  g = k++;
> +	  if (&h->q)
> +	    {
> +	      j = *f;
> +	      h->q = *f;
> +	    }
> +	  else
> +	    i = (long *) (h->q = *f);
> +	  *c++ = (long) f;
> +	  e += 6;
> +	}
> +    }
> +}
> +
> +int
> +main ()
> +{
> +  return 0;
> +}
> 
> 
> 	Jakub
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Jennifer Guild,
Dilip Upmanyu, Graham Norton HRB 21284 (AG Nuernberg)



More information about the Gcc-patches mailing list