From a09ad34709696a3d02ae588e7a595fd379b885b0 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Fri, 16 Nov 2018 17:43:49 +0100
Subject: [PATCH] re PR rtl-optimization/87475 (ICE in patch_jump_insn, at
 cfgrtl.c:1275)

	PR rtl-optimization/87475
	* cfgrtl.c (patch_jump_insn): Allow redirection failure for
	CROSSING_JUMP_P insns.
	(cfg_layout_redirect_edge_and_branch): Don't ICE if ret is NULL.

	* g++.dg/opt/pr87475.C: New test.

From-SVN: r266219
---
 gcc/ChangeLog                      | 7 +++++++
 gcc/cfgrtl.c                       | 9 +++++++--
 gcc/testsuite/ChangeLog            | 5 +++++
 gcc/testsuite/g++.dg/opt/pr87475.C | 7 +++++++
 4 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/opt/pr87475.C

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2362e708a8dd..984826d6c47f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2018-11-16  Jakub Jelinek  <jakub@redhat.com>
+
+	PR rtl-optimization/87475
+	* cfgrtl.c (patch_jump_insn): Allow redirection failure for
+	CROSSING_JUMP_P insns.
+	(cfg_layout_redirect_edge_and_branch): Don't ICE if ret is NULL.
+
 2018-11-16  Uros Bizjak  <ubizjak@gmail.com>
 
 	PR target/88051
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 3d4a114cbbb9..411a0245f545 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -1268,11 +1268,13 @@ patch_jump_insn (rtx_insn *insn, rtx_insn *old_label, basic_block new_bb)
 
 	  /* If the substitution doesn't succeed, die.  This can happen
 	     if the back end emitted unrecognizable instructions or if
-	     target is exit block on some arches.  */
+	     target is exit block on some arches.  Or for crossing
+	     jumps.  */
 	  if (!redirect_jump (as_a <rtx_jump_insn *> (insn),
 			      block_label (new_bb), 0))
 	    {
-	      gcc_assert (new_bb == EXIT_BLOCK_PTR_FOR_FN (cfun));
+	      gcc_assert (new_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
+			  || CROSSING_JUMP_P (insn));
 	      return false;
 	    }
 	}
@@ -4460,6 +4462,9 @@ cfg_layout_redirect_edge_and_branch (edge e, basic_block dest)
   else
     ret = redirect_branch_edge (e, dest);
 
+  if (!ret)
+    return NULL;
+
   fixup_partition_crossing (ret);
   /* We don't want simplejumps in the insn stream during cfglayout.  */
   gcc_assert (!simplejump_p (BB_END (src)) || CROSSING_JUMP_P (BB_END (src)));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a00506d533dd..e3856f48282e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-11-16  Jakub Jelinek  <jakub@redhat.com>
+
+	PR rtl-optimization/87475
+	* g++.dg/opt/pr87475.C: New test.
+
 2018-11-16  Matthew Malcomson  <matthew.malcomson@arm.com>
 
 	* gcc.c-torture/execute/printf-2.c: Skip on wrapped boards.
diff --git a/gcc/testsuite/g++.dg/opt/pr87475.C b/gcc/testsuite/g++.dg/opt/pr87475.C
new file mode 100644
index 000000000000..5ed25b45246b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr87475.C
@@ -0,0 +1,7 @@
+// PR rtl-optimization/87475
+// { dg-do compile { target freorder } }
+// { dg-options "-O2 -freorder-blocks-and-partition -fmodulo-sched" }
+
+struct A { A (); ~A (); };
+int foo (A, A);
+void bar (bool x) { x ? foo (A (), A ()) : 0; }
-- 
GitLab