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

Reply via email to