Patchwork Remove vdefs when changing a normal call into noreturn call (PR tree-optimization/44539)

login
register
mail settings
Submitter Jakub Jelinek
Date June 25, 2010, 11:43 a.m.
Message ID <20100625114355.GI12443@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/56902/
State New
Headers show

Comments

Jakub Jelinek - June 25, 2010, 11:43 a.m.
Hi!

When a call has VDEF, but doesn't have lhs and is through noreturn discovery
changed into a noreturn call, we failed to remove the VDEF, which caused
verification errors.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux.
Ok for trunk?

Calling update_stmt unconditionally there isn't possible, as update_stmt
adds the stmt into MODIFIED_NORETURN_CALLS and thus
split_bbs_on_noreturn_calls hangs.  If it has lhs or vdef, the first
update_stmt call changes it and the next one won't call update_stmt anymore.

2010-06-25  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/44539
	* tree-cfgcleanup.c (fixup_noreturn_call): Call update_stmt even when
	the call doesn't have LHS, but has VDEF.

	* gcc.dg/pr44539.c: New test.


	Jakub
Richard Guenther - June 25, 2010, 11:48 a.m.
On Fri, 25 Jun 2010, Jakub Jelinek wrote:

> Hi!
> 
> When a call has VDEF, but doesn't have lhs and is through noreturn discovery
> changed into a noreturn call, we failed to remove the VDEF, which caused
> verification errors.
> 
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux.
> Ok for trunk?

Ok.

Thanks,
Richard.

> Calling update_stmt unconditionally there isn't possible, as update_stmt
> adds the stmt into MODIFIED_NORETURN_CALLS and thus
> split_bbs_on_noreturn_calls hangs.  If it has lhs or vdef, the first
> update_stmt call changes it and the next one won't call update_stmt anymore.
> 
> 2010-06-25  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR tree-optimization/44539
> 	* tree-cfgcleanup.c (fixup_noreturn_call): Call update_stmt even when
> 	the call doesn't have LHS, but has VDEF.
> 
> 	* gcc.dg/pr44539.c: New test.
> 
> --- gcc/tree-cfgcleanup.c.jj	2010-06-14 07:44:24.000000000 +0200
> +++ gcc/tree-cfgcleanup.c	2010-06-24 11:44:59.000000000 +0200
> @@ -591,6 +591,9 @@ fixup_noreturn_call (gimple stmt)
>        update_stmt (stmt);
>        changed = true;
>      }
> +  /* Similarly remove VDEF if there is any.  */
> +  else if (gimple_vdef (stmt))
> +    update_stmt (stmt);
>    return changed;
>  }
>  
> --- gcc/testsuite/gcc.dg/pr44539.c.jj	2010-06-24 11:45:16.000000000 +0200
> +++ gcc/testsuite/gcc.dg/pr44539.c	2010-06-24 11:44:26.000000000 +0200
> @@ -0,0 +1,29 @@
> +/* PR tree-optimization/44539 */
> +/* { dg-do compile } */
> +/* { dg-options "-ftracer -freorder-blocks -O2" } */
> +
> +void bar (int file);
> +extern int baz (void);
> +
> +void noret1 ()
> +{
> +  bar (0);
> +  __builtin_exit (0);
> +}
> +
> +void noret2 ()
> +{
> +  __builtin_exit (0);
> +}
> +
> +void bar (int i)
> +{
> +  if (baz ())
> +    noret1 (i);
> +}
> +
> +void foo (int i)
> +{
> +  if (~i) bar (i);
> +  i ? noret1 () : noret2 ();
> +}
> 
> 	Jakub
> 
>

Patch

--- gcc/tree-cfgcleanup.c.jj	2010-06-14 07:44:24.000000000 +0200
+++ gcc/tree-cfgcleanup.c	2010-06-24 11:44:59.000000000 +0200
@@ -591,6 +591,9 @@  fixup_noreturn_call (gimple stmt)
       update_stmt (stmt);
       changed = true;
     }
+  /* Similarly remove VDEF if there is any.  */
+  else if (gimple_vdef (stmt))
+    update_stmt (stmt);
   return changed;
 }
 
--- gcc/testsuite/gcc.dg/pr44539.c.jj	2010-06-24 11:45:16.000000000 +0200
+++ gcc/testsuite/gcc.dg/pr44539.c	2010-06-24 11:44:26.000000000 +0200
@@ -0,0 +1,29 @@ 
+/* PR tree-optimization/44539 */
+/* { dg-do compile } */
+/* { dg-options "-ftracer -freorder-blocks -O2" } */
+
+void bar (int file);
+extern int baz (void);
+
+void noret1 ()
+{
+  bar (0);
+  __builtin_exit (0);
+}
+
+void noret2 ()
+{
+  __builtin_exit (0);
+}
+
+void bar (int i)
+{
+  if (baz ())
+    noret1 (i);
+}
+
+void foo (int i)
+{
+  if (~i) bar (i);
+  i ? noret1 () : noret2 ();
+}