re PR rtl-optimization/85393 (Miscompilation with hot/cold partitioning starting...
authorJakub Jelinek <jakub@redhat.com>
Fri, 13 Apr 2018 19:55:15 +0000 (21:55 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 13 Apr 2018 19:55:15 +0000 (21:55 +0200)
PR rtl-optimization/85393
* except.h (expand_dw2_landing_pad_for_region): Remove declaration.
* except.c (expand_dw2_landing_pad_for_region): Make static.
* bb-reorder.c (fix_up_crossing_landing_pad): In new_bb emit just
a label and unconditional jump to old_bb, rather than
expand_dw2_landing_pad_for_region insn(s) and jump to single_succ
basic block.

* g++.dg/opt/pr85393.C: New test.
* g++.dg/opt/pr85393-aux.cc: New file.

From-SVN: r259378

gcc/ChangeLog
gcc/bb-reorder.c
gcc/except.c
gcc/except.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr85393-aux.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/opt/pr85393.C [new file with mode: 0644]

index 2754c48ac49e811429f9287e197b2287f5ca28d1..96247862f447421940c0c62de0c8bf2b63f1e827 100644 (file)
@@ -1,5 +1,13 @@
 2018-04-13  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/85393
+       * except.h (expand_dw2_landing_pad_for_region): Remove declaration.
+       * except.c (expand_dw2_landing_pad_for_region): Make static.
+       * bb-reorder.c (fix_up_crossing_landing_pad): In new_bb emit just
+       a label and unconditional jump to old_bb, rather than
+       expand_dw2_landing_pad_for_region insn(s) and jump to single_succ
+       basic block.
+
        PR rtl-optimization/85376
        * simplify-rtx.c (simplify_const_unary_operation): For CLZ and CTZ and
        zero op0, if C?Z_DEFINED_VALUE_AT_ZERO is false, return NULL_RTX
index 8a65d6b3938c12969b94a7c7d4e392c1e4c90dc5..d2b41606a1422706d8b4b77d56b82db8551f1411 100644 (file)
@@ -1409,14 +1409,14 @@ get_uncond_jump_length (void)
 }
 
 /* The landing pad OLD_LP, in block OLD_BB, has edges from both partitions.
-   Duplicate the landing pad and split the edges so that no EH edge
-   crosses partitions.  */
+   Add a new landing pad that will just jump to the old one and split the
+   edges so that no EH edge crosses partitions.  */
 
 static void
 fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb)
 {
   eh_landing_pad new_lp;
-  basic_block new_bb, last_bb, post_bb;
+  basic_block new_bb, last_bb;
   rtx_insn *jump;
   unsigned new_partition;
   edge_iterator ei;
@@ -1431,24 +1431,20 @@ fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb)
   /* Put appropriate instructions in new bb.  */
   rtx_code_label *new_label = emit_label (new_lp->landing_pad);
 
-  expand_dw2_landing_pad_for_region (old_lp->region);
-
-  post_bb = BLOCK_FOR_INSN (old_lp->landing_pad);
-  post_bb = single_succ (post_bb);
-  rtx_code_label *post_label = block_label (post_bb);
-  jump = emit_jump_insn (targetm.gen_jump (post_label));
-  JUMP_LABEL (jump) = post_label;
+  rtx_code_label *old_label = block_label (old_bb);
+  jump = emit_jump_insn (targetm.gen_jump (old_label));
+  JUMP_LABEL (jump) = old_label;
 
   /* Create new basic block to be dest for lp.  */
   last_bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
   new_bb = create_basic_block (new_label, jump, last_bb);
   new_bb->aux = last_bb->aux;
-  new_bb->count = post_bb->count;
+  new_bb->count = old_bb->count;
   last_bb->aux = new_bb;
 
   emit_barrier_after_bb (new_bb);
 
-  make_single_succ_edge (new_bb, post_bb, 0);
+  make_single_succ_edge (new_bb, old_bb, 0);
 
   /* Make sure new bb is in the other partition.  */
   new_partition = BB_PARTITION (old_bb);
@@ -1457,7 +1453,7 @@ fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb)
 
   /* Fix up the edges.  */
   for (ei = ei_start (old_bb->preds); (e = ei_safe_edge (ei)) != NULL; )
-    if (BB_PARTITION (e->src) == new_partition)
+    if (e->src != new_bb && BB_PARTITION (e->src) == new_partition)
       {
        rtx_insn *insn = BB_END (e->src);
        rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
index 53e57732ea85bad245714bb60c82eec7cd610df9..ba42bf68b43e9f4411c927e8e6fc718c5a5dc962 100644 (file)
@@ -947,7 +947,7 @@ emit_to_new_bb_before (rtx_insn *seq, rtx_insn *insn)
    at the rtl level.  Emit the code required by the target at a landing
    pad for the given region.  */
 
-void
+static void
 expand_dw2_landing_pad_for_region (eh_region region)
 {
   if (targetm.have_exception_receiver ())
index 229e446cb655499fb4024a07aa6b098f07126c67..caa375ef670b0797405c7af65ec3778207fa0782 100644 (file)
@@ -243,7 +243,6 @@ extern rtx expand_builtin_dwarf_sp_column (void);
 extern void expand_builtin_eh_return (tree, tree);
 extern void expand_eh_return (void);
 extern rtx expand_builtin_extend_pointer (tree);
-extern void expand_dw2_landing_pad_for_region (eh_region);
 
 typedef tree (*duplicate_eh_regions_map) (tree, void *);
 extern hash_map<void *, void *> *duplicate_eh_regions
index 90ffbf86c9e487d1991689035e69dc6307c265e1..88c7185cf4664adcd8555ef98c47c075b2870a07 100644 (file)
@@ -1,5 +1,9 @@
 2018-04-13  Jakub Jelinek  <jakub@redhat.com>
 
+       PR rtl-optimization/85393
+       * g++.dg/opt/pr85393.C: New test.
+       * g++.dg/opt/pr85393-aux.cc: New file.
+
        PR rtl-optimization/85376
        * gcc.dg/pr85376.c: New test.
 
diff --git a/gcc/testsuite/g++.dg/opt/pr85393-aux.cc b/gcc/testsuite/g++.dg/opt/pr85393-aux.cc
new file mode 100644 (file)
index 0000000..45e4767
--- /dev/null
@@ -0,0 +1,5 @@
+// PR rtl-optimization/85393
+// { dg-do compile }
+// { dg-options "" }
+
+void foo (char const *) {}
diff --git a/gcc/testsuite/g++.dg/opt/pr85393.C b/gcc/testsuite/g++.dg/opt/pr85393.C
new file mode 100644 (file)
index 0000000..a2a3162
--- /dev/null
@@ -0,0 +1,29 @@
+// PR rtl-optimization/85393
+// { dg-do run { target c++11 } }
+// { dg-options "-O2" }
+// { dg-additional-sources "pr85393-aux.cc" }
+
+#include <stdexcept>
+#include <vector>
+
+void foo (char const *s);
+struct S { ~S () noexcept (false) { throw std::runtime_error ("foo"); } };
+
+int
+main (int argc, char *argv[])
+{
+  std::vector <std::vector <char> > args;
+  try
+    {
+      {
+        S k;
+        foo ("A");
+      }
+
+      if (argv)
+        throw std::runtime_error ("foo");
+      args.push_back ({});
+    }
+  catch (std::runtime_error const& e)
+    {}
+}