combine: Make code after a new trap unreachable (PR78342)
authorSegher Boessenkool <segher@kernel.crashing.org>
Tue, 29 Nov 2016 02:02:45 +0000 (03:02 +0100)
committerSegher Boessenkool <segher@gcc.gnu.org>
Tue, 29 Nov 2016 02:02:45 +0000 (03:02 +0100)
Combine can turn a conditional trap into an unconditional trap.  If it
does that it should make the code after it unreachable (an unconditional
trap should be the last insn in its bb, and that bb has no successors).

This patch seems to work.  It is hard to be sure, this is very hard to
trigger.  Quite a few other passes look like they need something similar
as well, but I don't see anything else handling it yet either.

PR rtl-optimization/78342
* combine.c: Include "cfghooks.h".
(try_combine): If we create an unconditional trap, break the basic
block in two just after it, and remove the edge between; also, set
the *new_direct_jump_p flag so that cleanup_cfg is run.

From-SVN: r242947

gcc/ChangeLog
gcc/combine.c

index 900f9b355d74ca1a49b2fbcb42ba2fd3957edae0..07bcc26b5b62b1aa7607f8da1395e19c9851c86e 100644 (file)
@@ -1,3 +1,11 @@
+2016-11-28  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       PR rtl-optimization/78342
+       * combine.c: Include "cfghooks.h".
+       (try_combine): If we create an unconditional trap, break the basic
+       block in two just after it, and remove the edge between; also, set
+       the *new_direct_jump_p flag so that cleanup_cfg is run.
+
 2016-11-28  Segher Boessenkool  <segher@kernel.crashing.org>
 
        * simplify-rtx.c (simplify_truncation): Handle truncate of zero_extract
index 45d4048b13dfe8c3484d991847698e87f344a7ce..41f69daf7f3bbe715701640b174296fd15b4ac30 100644 (file)
@@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "rtl.h"
 #include "tree.h"
+#include "cfghooks.h"
 #include "predict.h"
 #include "df.h"
 #include "memmodel.h"
@@ -4620,6 +4621,25 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
       update_cfg_for_uncondjump (undobuf.other_insn);
     }
 
+  if (GET_CODE (PATTERN (i3)) == TRAP_IF
+      && XEXP (PATTERN (i3), 0) == const1_rtx)
+    {
+      basic_block bb = BLOCK_FOR_INSN (i3);
+      gcc_assert (bb);
+      remove_edge (split_block (bb, i3));
+      *new_direct_jump_p = 1;
+    }
+
+  if (undobuf.other_insn
+      && GET_CODE (PATTERN (undobuf.other_insn)) == TRAP_IF
+      && XEXP (PATTERN (undobuf.other_insn), 0) == const1_rtx)
+    {
+      basic_block bb = BLOCK_FOR_INSN (undobuf.other_insn);
+      gcc_assert (bb);
+      remove_edge (split_block (bb, undobuf.other_insn));
+      *new_direct_jump_p = 1;
+    }
+
   /* A noop might also need cleaning up of CFG, if it comes from the
      simplification of a jump.  */
   if (JUMP_P (i3)