Patchwork Fix missing EH updates in execute_cse_sincos (PR tree-optimization/54563)

login
register
mail settings
Submitter Jakub Jelinek
Date Sept. 16, 2012, 3:55 p.m.
Message ID <20120916155520.GS22619@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/184131/
State New
Headers show

Comments

Jakub Jelinek - Sept. 16, 2012, 3:55 p.m.
Hi!

As discussed in the PR, this patch fixes the ICE by calling
gimple_purge_dead_eh_edges if the last stmt has been replaced by the pass.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Still, I think it would be nice if e.g. powf or cosl were throw() in C++, at
least if they are treated as builtins or at least in C++11 where they are
library functions.

2012-09-16  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/54563
	* tree-ssa-math-opts.c (execute_cse_sincos): Call
	gimple_purge_dead_eh_edges if last call has been changed.

	* g++.dg/torture/pr54563.C: New test.


	Jakub
Richard Guenther - Sept. 17, 2012, 9:05 a.m.
On Sun, Sep 16, 2012 at 5:55 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> As discussed in the PR, this patch fixes the ICE by calling
> gimple_purge_dead_eh_edges if the last stmt has been replaced by the pass.
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> Still, I think it would be nice if e.g. powf or cosl were throw() in C++, at
> least if they are treated as builtins or at least in C++11 where they are
> library functions.

Ok.

Thanks,
Richard.

> 2012-09-16  Jakub Jelinek  <jakub@redhat.com>
>
>         PR tree-optimization/54563
>         * tree-ssa-math-opts.c (execute_cse_sincos): Call
>         gimple_purge_dead_eh_edges if last call has been changed.
>
>         * g++.dg/torture/pr54563.C: New test.
>
> --- gcc/tree-ssa-math-opts.c.jj 2012-09-12 10:57:02.000000000 +0200
> +++ gcc/tree-ssa-math-opts.c    2012-09-14 21:03:05.546319590 +0200
> @@ -1378,12 +1378,18 @@ execute_cse_sincos (void)
>    FOR_EACH_BB (bb)
>      {
>        gimple_stmt_iterator gsi;
> +      bool cleanup_eh = false;
>
>        for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
>          {
>           gimple stmt = gsi_stmt (gsi);
>           tree fndecl;
>
> +         /* Only the last stmt in a bb could throw, no need to call
> +            gimple_purge_dead_eh_edges if we change something in the middle
> +            of a basic block.  */
> +         cleanup_eh = false;
> +
>           if (is_gimple_call (stmt)
>               && gimple_call_lhs (stmt)
>               && (fndecl = gimple_call_fndecl (stmt))
> @@ -1421,6 +1427,7 @@ execute_cse_sincos (void)
>                       gimple_set_location (new_stmt, loc);
>                       unlink_stmt_vdef (stmt);
>                       gsi_replace (&gsi, new_stmt, true);
> +                     cleanup_eh = true;
>                       if (gimple_vdef (stmt))
>                         release_ssa_name (gimple_vdef (stmt));
>                     }
> @@ -1443,6 +1450,7 @@ execute_cse_sincos (void)
>                       gimple_set_location (new_stmt, loc);
>                       unlink_stmt_vdef (stmt);
>                       gsi_replace (&gsi, new_stmt, true);
> +                     cleanup_eh = true;
>                       if (gimple_vdef (stmt))
>                         release_ssa_name (gimple_vdef (stmt));
>                     }
> @@ -1460,6 +1468,7 @@ execute_cse_sincos (void)
>                       gimple_set_location (new_stmt, loc);
>                       unlink_stmt_vdef (stmt);
>                       gsi_replace (&gsi, new_stmt, true);
> +                     cleanup_eh = true;
>                       if (gimple_vdef (stmt))
>                         release_ssa_name (gimple_vdef (stmt));
>                     }
> @@ -1469,6 +1478,8 @@ execute_cse_sincos (void)
>                 }
>             }
>         }
> +      if (cleanup_eh)
> +       cfg_changed |= gimple_purge_dead_eh_edges (bb);
>      }
>
>    statistics_counter_event (cfun, "sincos statements inserted",
> --- gcc/testsuite/g++.dg/torture/pr54563.C.jj   2012-09-14 21:05:07.514702413 +0200
> +++ gcc/testsuite/g++.dg/torture/pr54563.C      2012-09-14 21:04:40.000000000 +0200
> @@ -0,0 +1,14 @@
> +// PR tree-optimization/54563
> +// { dg-do compile }
> +
> +extern "C" float powf (float, float);
> +struct S { ~S (); };
> +double bar ();
> +double x;
> +
> +void
> +foo ()
> +{
> +  S s;
> +  x = powf (bar (), 2.);
> +}
>
>         Jakub

Patch

--- gcc/tree-ssa-math-opts.c.jj	2012-09-12 10:57:02.000000000 +0200
+++ gcc/tree-ssa-math-opts.c	2012-09-14 21:03:05.546319590 +0200
@@ -1378,12 +1378,18 @@  execute_cse_sincos (void)
   FOR_EACH_BB (bb)
     {
       gimple_stmt_iterator gsi;
+      bool cleanup_eh = false;
 
       for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
         {
 	  gimple stmt = gsi_stmt (gsi);
 	  tree fndecl;
 
+	  /* Only the last stmt in a bb could throw, no need to call
+	     gimple_purge_dead_eh_edges if we change something in the middle
+	     of a basic block.  */
+	  cleanup_eh = false;
+
 	  if (is_gimple_call (stmt)
 	      && gimple_call_lhs (stmt)
 	      && (fndecl = gimple_call_fndecl (stmt))
@@ -1421,6 +1427,7 @@  execute_cse_sincos (void)
 		      gimple_set_location (new_stmt, loc);
 		      unlink_stmt_vdef (stmt);
 		      gsi_replace (&gsi, new_stmt, true);
+		      cleanup_eh = true;
 		      if (gimple_vdef (stmt))
 			release_ssa_name (gimple_vdef (stmt));
 		    }
@@ -1443,6 +1450,7 @@  execute_cse_sincos (void)
 		      gimple_set_location (new_stmt, loc);
 		      unlink_stmt_vdef (stmt);
 		      gsi_replace (&gsi, new_stmt, true);
+		      cleanup_eh = true;
 		      if (gimple_vdef (stmt))
 			release_ssa_name (gimple_vdef (stmt));
 		    }
@@ -1460,6 +1468,7 @@  execute_cse_sincos (void)
 		      gimple_set_location (new_stmt, loc);
 		      unlink_stmt_vdef (stmt);
 		      gsi_replace (&gsi, new_stmt, true);
+		      cleanup_eh = true;
 		      if (gimple_vdef (stmt))
 			release_ssa_name (gimple_vdef (stmt));
 		    }
@@ -1469,6 +1478,8 @@  execute_cse_sincos (void)
 		}
 	    }
 	}
+      if (cleanup_eh)
+	cfg_changed |= gimple_purge_dead_eh_edges (bb);
     }
 
   statistics_counter_event (cfun, "sincos statements inserted",
--- gcc/testsuite/g++.dg/torture/pr54563.C.jj	2012-09-14 21:05:07.514702413 +0200
+++ gcc/testsuite/g++.dg/torture/pr54563.C	2012-09-14 21:04:40.000000000 +0200
@@ -0,0 +1,14 @@ 
+// PR tree-optimization/54563
+// { dg-do compile }
+
+extern "C" float powf (float, float);
+struct S { ~S (); };
+double bar ();
+double x;
+
+void
+foo ()
+{
+  S s;
+  x = powf (bar (), 2.);
+}