diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7f4e311087fbfb875c11eda22082b3363fbc859f..ba56e636584e9e5bfa55cf0ae4a0021aec2f2e64 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2016-10-03  Jeff Law  <law@redhat.com>
+
+	PR tree-optimization/71550
+	PR tree-optimization/71403
+	* tree-ssa-threadbackward.c: Include tree-vectorizer.h
+	(profitable_jump_thread_path): Also return boolean indicating if
+	the realized path will create an irreducible loop.
+	Remove loop depth tests from 71403.
+	(fsm_find_control_statement_thread_paths): Remove loop depth tests
+	from 71403.  If threading will create an irreducible loop, then
+	throw away loop iteration and related information.
+
 2016-10-03  Uros Bizjak  <ubizjak@gmail.com>
 
 	* configure.ac (strict_warn): Merge -Wmissing-format-attribute and
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d0ed6a679b4a710a1d16f83f7d5b10e168c4d0d0..9e6246455cadbd332f35101a0a8c012d946e2308 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2016-09-26  Jeff Law  <law@redhat.com>
+
+	PR tree-optimization/71550
+	PR tree-optimization/71403
+	* gcc.c-torture/execute/pr71550.c: New test.
+
 2016-10-03  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
 
 	* gcc.target/avr/torture/builtins-error.c: Add -ffat-lto-objects
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr71550.c b/gcc/testsuite/gcc.c-torture/execute/pr71550.c
new file mode 100644
index 0000000000000000000000000000000000000000..8d1ecdaa06dec45ce7af0f33c7e3fd705886c50e
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr71550.c
@@ -0,0 +1,26 @@
+
+extern void exit (int);
+
+int a = 3, b, c, f, g, h;
+unsigned d;
+char *e;
+
+int
+main ()
+{
+  for (; a; a--)
+    {
+      int i;
+      if (h && i)
+	__builtin_printf ("%d%d", c, f);
+      i = 0;
+      for (; i < 2; i++)
+	if (g)
+	  for (; d < 10; d++)
+	    b = *e;
+      i = 0;
+      for (; i < 1; i++)
+	;
+    }
+  exit (0);
+}
diff --git a/gcc/tree-ssa-threadbackward.c b/gcc/tree-ssa-threadbackward.c
index 6b522adcefbefddaa7a48c668a1e2af3afd95e44..fd7d855449d7b85f3e2d834d615e7dab23a5674c 100644
--- a/gcc/tree-ssa-threadbackward.c
+++ b/gcc/tree-ssa-threadbackward.c
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-ssa.h"
 #include "tree-phinodes.h"
 #include "tree-inline.h"
+#include "tree-vectorizer.h"
 
 static int max_threaded_paths;
 
@@ -110,7 +111,8 @@ fsm_find_thread_path (basic_block start_bb, basic_block end_bb,
 
 static edge
 profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
-			     basic_block bbi, tree name, tree arg, bool speed_p)
+			     basic_block bbi, tree name, tree arg, bool speed_p,
+			     bool *creates_irreducible_loop)
 {
   /* Note BBI is not in the path yet, hence the +1 in the test below
      to make sure BBI is accounted for in the path length test.  */
@@ -296,12 +298,12 @@ profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
       return NULL;
     }
 
-  bool creates_irreducible_loop = false;
+  *creates_irreducible_loop = false;
   if (threaded_through_latch
       && loop == taken_edge->dest->loop_father
       && (determine_bb_domination_status (loop, taken_edge->dest)
 	  == DOMST_NONDOMINATING))
-    creates_irreducible_loop = true;
+    *creates_irreducible_loop = true;
 
   if (path_crosses_loops)
     {
@@ -343,7 +345,7 @@ profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
      the path -- in that case there's little the traditional loop
      optimizer would have done anyway, so an irreducible loop is not
      so bad.  */
-  if (!threaded_multiway_branch && creates_irreducible_loop
+  if (!threaded_multiway_branch && *creates_irreducible_loop
       && (n_insns * PARAM_VALUE (PARAM_FSM_SCALE_PATH_STMTS)
 	  > path_length * PARAM_VALUE (PARAM_FSM_SCALE_PATH_BLOCKS)))
 
@@ -479,9 +481,6 @@ fsm_find_control_statement_thread_paths (tree name,
       seen_loop_phi = true;
     }
 
-  if (bb_loop_depth (last_bb_in_path) > bb_loop_depth (var_bb))
-    return;
-
   /* Following the chain of SSA_NAME definitions, we jumped from a definition in
      LAST_BB_IN_PATH to a definition in VAR_BB.  When these basic blocks are
      different, append to PATH the blocks from LAST_BB_IN_PATH to VAR_BB.  */
@@ -528,9 +527,7 @@ fsm_find_control_statement_thread_paths (tree name,
 	 NEXT_PATH.  Don't add them here to avoid pollution.  */
       for (unsigned int i = 0; i < next_path->length () - 1; i++)
 	{
-	  if (visited_bbs->contains ((*next_path)[i])
-	      || (bb_loop_depth (last_bb_in_path)
-		  > bb_loop_depth ((*next_path)[i])))
+	  if (visited_bbs->contains ((*next_path)[i]))
 	    {
 	      vec_free (next_path);
 	      return;
@@ -580,14 +577,16 @@ fsm_find_control_statement_thread_paths (tree name,
 
 	  /* If this is a profitable jump thread path, then convert it
 	     into the canonical form and register it.  */
+	  bool irreducible = false;
 	  edge taken_edge = profitable_jump_thread_path (path, bbi, name, arg,
-							 speed_p);
+							 speed_p, &irreducible);
 	  if (taken_edge)
 	    {
-	      if (bb_loop_depth (taken_edge->src)
-		  >= bb_loop_depth (taken_edge->dest))
-		convert_and_register_jump_thread_path (path, taken_edge);
+	      convert_and_register_jump_thread_path (path, taken_edge);
 	      path->pop ();
+
+	      if (irreducible)
+		vect_free_loop_info_assumptions ((*path)[0]->loop_father);
 	    }
 	}
     }
@@ -606,14 +605,17 @@ fsm_find_control_statement_thread_paths (tree name,
 	     block at this point.  So we can just pop it.  */
 	  path->pop ();
 
+	  bool irreducible = false;
 	  edge taken_edge = profitable_jump_thread_path (path, var_bb,
-						         name, arg, speed_p);
+						         name, arg, speed_p,
+							 &irreducible);
 	  if (taken_edge)
 	    {
-	      if (bb_loop_depth (taken_edge->src)
-		  >= bb_loop_depth (taken_edge->dest))
-		convert_and_register_jump_thread_path (path, taken_edge);
+	      convert_and_register_jump_thread_path (path, taken_edge);
 	      path->pop ();
+
+	      if (irreducible)
+		vect_free_loop_info_assumptions ((*path)[0]->loop_father);
 	    }
 
 	  /* And put the current block back onto the path so that the