On June 30, 2017 7:33:34 PM GMT+02:00, Jakub Jelinek <ja...@redhat.com> wrote:
>Hi!
>
>The following testcases now ICE on the trunk.  The problem is that
>fix_up_fall_thru_edges doesn't notice asm goto does have a fallthru
>edge
>when it has 3 edges and the EDGE_FALLTHRU is only 3rd.  Fixed by using
>find_fallthru_edge if we didn't find it among the first 2 edges no
>matter
>what the branch kind is.
>
>Another bug is that the cond_jump variable is not really cleared and
>thus
>once it is set to something on one of the bbs, it could be used later
>on
>completely different bb.  This got fixed by moving the vars into the
>scopes
>where they IMHO belong.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

>2017-06-30  Jakub Jelinek  <ja...@redhat.com>
>
>       PR sanitizer/81262
>       * bb-reorder.c (fix_up_fall_thru_edges): Move variable declarations to
>       the right scopes, make sure cond_jump isn't preserved between multiple
>       iterations.  Search for fallthru edge whenever there are 3+ edges and
>       use find_fallthru_edge for it.
>
>       * gcc.c-torture/compile/pr81262.c: New test.
>       * g++.dg/ubsan/pr81262.C: New test.
>
>--- gcc/bb-reorder.c.jj        2017-06-30 09:49:32.000000000 +0200
>+++ gcc/bb-reorder.c   2017-06-30 13:31:06.709898101 +0200
>@@ -1812,18 +1812,15 @@ static void
> fix_up_fall_thru_edges (void)
> {
>   basic_block cur_bb;
>-  basic_block new_bb;
>-  edge succ1;
>-  edge succ2;
>-  edge fall_thru;
>-  edge cond_jump = NULL;
>-  bool cond_jump_crosses;
>-  int invert_worked;
>-  rtx_insn *old_jump;
>-  rtx_code_label *fall_thru_label;
> 
>   FOR_EACH_BB_FN (cur_bb, cfun)
>     {
>+      edge succ1;
>+      edge succ2;
>+      edge fall_thru = NULL;
>+      edge cond_jump = NULL;
>+      rtx_code_label *fall_thru_label;
>+
>       fall_thru = NULL;
>       if (EDGE_COUNT (cur_bb->succs) > 0)
>       succ1 = EDGE_SUCC (cur_bb, 0);
>@@ -1849,20 +1846,8 @@ fix_up_fall_thru_edges (void)
>         fall_thru = succ2;
>         cond_jump = succ1;
>       }
>-      else if (succ1
>-             && (block_ends_with_call_p (cur_bb)
>-                 || can_throw_internal (BB_END (cur_bb))))
>-      {
>-        edge e;
>-        edge_iterator ei;
>-
>-        FOR_EACH_EDGE (e, ei, cur_bb->succs)
>-          if (e->flags & EDGE_FALLTHRU)
>-            {
>-              fall_thru = e;
>-              break;
>-            }
>-      }
>+      else if (succ2 && EDGE_COUNT (cur_bb->succs) > 2)
>+      fall_thru = find_fallthru_edge (cur_bb->succs);
> 
>    if (fall_thru && (fall_thru->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)))
>       {
>@@ -1873,9 +1858,9 @@ fix_up_fall_thru_edges (void)
>             /* The fall_thru edge crosses; now check the cond jump edge, if
>                it exists.  */
> 
>-            cond_jump_crosses = true;
>-            invert_worked  = 0;
>-            old_jump = BB_END (cur_bb);
>+            bool cond_jump_crosses = true;
>+            int invert_worked = 0;
>+            rtx_insn *old_jump = BB_END (cur_bb);
> 
>             /* Find the jump instruction, if there is one.  */
> 
>@@ -1895,12 +1880,13 @@ fix_up_fall_thru_edges (void)
>                     /* Find label in fall_thru block. We've already added
>                        any missing labels, so there must be one.  */
> 
>-                    fall_thru_label = block_label (fall_thru->dest);
>+                    rtx_code_label *fall_thru_label
>+                      = block_label (fall_thru->dest);
> 
>                     if (old_jump && fall_thru_label)
>                       {
>-                        rtx_jump_insn *old_jump_insn =
>-                              dyn_cast <rtx_jump_insn *> (old_jump);
>+                        rtx_jump_insn *old_jump_insn
>+                          = dyn_cast <rtx_jump_insn *> (old_jump);
>                         if (old_jump_insn)
>                           invert_worked = invert_jump (old_jump_insn,
>                                                        fall_thru_label, 0);
>@@ -1931,7 +1917,7 @@ fix_up_fall_thru_edges (void)
>                    becomes EDGE_CROSSING.  */
> 
>                 fall_thru->flags &= ~EDGE_CROSSING;
>-                new_bb = force_nonfallthru (fall_thru);
>+                basic_block new_bb = force_nonfallthru (fall_thru);
> 
>                 if (new_bb)
>                   {
>--- gcc/testsuite/gcc.c-torture/compile/pr81262.c.jj   2017-06-30
>13:30:06.493624559 +0200
>+++ gcc/testsuite/gcc.c-torture/compile/pr81262.c      2017-06-30
>13:30:15.000521931 +0200
>@@ -0,0 +1,14 @@
>+/* PR sanitizer/81262 */
>+
>+void bar (void) __attribute__((cold, noreturn));
>+
>+int
>+foo (void)
>+{
>+  asm goto ("" : : : : l1, l2);
>+  bar ();
>+ l1:
>+  return 1;
>+ l2:
>+  return 0;
>+}
>--- gcc/testsuite/g++.dg/ubsan/pr81262.C.jj    2017-06-30
>13:25:59.339606262 +0200
>+++ gcc/testsuite/g++.dg/ubsan/pr81262.C       2017-06-30 13:26:08.563494984
>+0200
>@@ -0,0 +1,14 @@
>+// PR sanitizer/81262
>+// { dg-do compile }
>+// { dg-options "-O2 -fsanitize=unreachable" }
>+
>+int
>+foo ()
>+{
>+  asm goto ("" : : : : l1, l2);
>+  __builtin_unreachable ();
>+ l1:
>+  return 1;
>+ l2:
>+  return 0;
>+}
>
>       Jakub

Reply via email to