On February 5, 2019 4:32:29 PM GMT+01:00, Jakub Jelinek <ja...@redhat.com> 
wrote:
>Hi!
>
>RTL DCE is called in different modes, sometimes it is allowed to alter
>cfg,
>in other cases it is not.  The following testcase ICEs because when it
>is
>not allowed to alter cfg (combiner's df_analyze) we remove a noop move
>that
>was considered to potentially throw and that made a bb unreachable
>(which
>the pass didn't like), but even removing those unreachable bbs would
>ICE
>anyway, as the algorithm is for !can_alter_cfg not really prepared to
>see
>bbs and edges being removed.
>
>So, the following patch does 3 things:
>1) doesn't delete noop moves if they can
>   throw and we can't alter cfg or delete dead exceptions
>2) instead of setting must_clean blindly for any CALL_INSNs, it instead
>   sets it accurately from delete_insn_and_edges return value
>3) it asserts that if !can_alter_cfg we don't actually have must_clean
>set
>
>Bootstrapped/regtested on powerpc64{,le}-linux, ok for trunk?

OK. 

Richard. 

>2019-02-05  Jakub Jelinek  <ja...@redhat.com>
>
>       PR target/89188
>       * dce.c (delete_unmarked_insns): Don't remove no-op moves if they
>       can throw, non-call exceptions are enabled and we can't delete
>       dead exceptions or alter cfg.  Set must_clean if
>       delete_insn_and_edges returns true, don't set it blindly for calls.
>       Assert that delete_unreachable_blocks is called only if can_alter_cfg.
>
>       * g++.dg/opt/pr89188.C: New test.
>
>--- gcc/dce.c.jj       2019-02-05 10:04:16.984062429 +0100
>+++ gcc/dce.c  2019-02-05 10:53:47.655584503 +0100
>@@ -584,7 +584,12 @@ delete_unmarked_insns (void)
>         rtx turn_into_use = NULL_RTX;
> 
>         /* Always delete no-op moves.  */
>-        if (noop_move_p (insn))
>+        if (noop_move_p (insn)
>+            /* Unless the no-op move can throw and we are not allowed
>+               to alter cfg.  */
>+            && (!cfun->can_throw_non_call_exceptions
>+                || (cfun->can_delete_dead_exceptions && can_alter_cfg)
>+                || insn_nothrow_p (insn)))
>           {
>             if (RTX_FRAME_RELATED_P (insn))
>               turn_into_use
>@@ -627,12 +632,6 @@ delete_unmarked_insns (void)
>            for the destination regs in order to avoid dangling notes.  */
>         remove_reg_equal_equiv_notes_for_defs (insn);
> 
>-        /* If a pure or const call is deleted, this may make the cfg
>-           have unreachable blocks.  We rememeber this and call
>-           delete_unreachable_blocks at the end.  */
>-        if (CALL_P (insn))
>-          must_clean = true;
>-
>         if (turn_into_use)
>           {
>             /* Don't remove frame related noop moves if they cary
>@@ -645,12 +644,15 @@ delete_unmarked_insns (void)
>           }
>         else
>           /* Now delete the insn.  */
>-          delete_insn_and_edges (insn);
>+          must_clean |= delete_insn_and_edges (insn);
>       }
> 
>   /* Deleted a pure or const call.  */
>   if (must_clean)
>-    delete_unreachable_blocks ();
>+    {
>+      gcc_assert (can_alter_cfg);
>+      delete_unreachable_blocks ();
>+    }
> }
> 
> 
>--- gcc/testsuite/g++.dg/opt/pr89188.C.jj      2019-02-04 14:20:57.714851393
>+0100
>+++ gcc/testsuite/g++.dg/opt/pr89188.C 2019-02-04 14:52:09.988782531
>+0100
>@@ -0,0 +1,5 @@
>+// PR target/89188
>+// { dg-do compile { target c++11 } }
>+// { dg-options "-Og -flive-range-shrinkage -fnon-call-exceptions" }
>+
>+#include "../torture/pr88861.C"
>
>       Jakub

Reply via email to