Hi! As the testcase shows, with -fnon-call-exceptions RTL DSE can sometimes remove possibly throwing stores and we then ICE because dead EH edges have not been cleaned up.
This patch attempts to solve this similarly to how postreload-cse handles it. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2015-01-21 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/62078 * dse.c: Include cfgcleanup.h. (rest_of_handle_dse): For -fnon-call-exceptions, if DSE removed anything call purge_all_dead_edges and cleanup_cfg at the end of the pass. * g++.dg/opt/pr62078.C: New test. --- gcc/dse.c.jj 2015-01-15 20:25:30.000000000 +0100 +++ gcc/dse.c 2015-01-21 17:02:17.346184443 +0100 @@ -81,6 +81,7 @@ along with GCC; see the file COPYING3. #include "gimple.h" #include "gimple-ssa.h" #include "rtl-iter.h" +#include "cfgcleanup.h" /* This file contains three techniques for performing Dead Store Elimination (dse). @@ -3746,6 +3747,14 @@ rest_of_handle_dse (void) if (dump_file) fprintf (dump_file, "dse: local deletions = %d, global deletions = %d, spill deletions = %d\n", locally_deleted, globally_deleted, spill_deleted); + + /* DSE can eliminate potentially-trapping MEMs. + Remove any EH edges associated with them. */ + if ((locally_deleted || globally_deleted) + && cfun->can_throw_non_call_exceptions + && purge_all_dead_edges ()) + cleanup_cfg (0); + return 0; } --- gcc/testsuite/g++.dg/opt/pr62078.C.jj 2015-01-21 17:13:10.302543942 +0100 +++ gcc/testsuite/g++.dg/opt/pr62078.C 2015-01-21 17:12:44.000000000 +0100 @@ -0,0 +1,36 @@ +/* PR rtl-optimization/62078 */ +/* { dg-do compile } */ +/* { dg-options "-Og -fdelete-dead-exceptions -fnon-call-exceptions" } */ + +struct A { virtual ~A (); }; +struct B : A {}; +struct C : B {}; +struct D : C {}; +struct E : D {}; +struct F : E {}; +struct G : F {}; +struct H : G {}; +struct I : H {}; +struct J : I {}; +struct K : J {}; +struct L : K {}; +struct M : L {}; +struct N : M {}; +struct O : N {}; +struct P : O {}; +struct Q : P {}; +struct R : Q {}; +struct S : R {}; +struct T : S {}; +struct U : T {}; +struct V : U {}; +struct W : V {}; +struct X : W {}; +struct Y : X {}; +struct Z : Y {}; + +void +foo () +{ + Z z; +} Jakub