| 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
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.); +}