This avoids regressing gcc.dg/tree-ssa/pr21417.c with the fix for PR72772 where after it a forwarder block no longer is present. It's easy to simply create it when FSM threading faces the situation that the edge ending the path enters a loop.
I also fixed the costs for obviously related anon SSA names (when they are the same). Bootstrap and regtest running on x86_64-unknown-linux-gnu, I'll apply if that finishes successfully. Richard. 2016-08-05 Richard Biener <rguent...@suse.de> * tree-ssa-threadbackward.c: Include cfghooks.h. (profitable_jump_thread_path): Treat same SSA names related. (fsm_find_control_statement_thread_paths): When the taken edge enters a loop split it instead of giving up. Index: gcc/tree-ssa-threadbackward.c =================================================================== --- gcc/tree-ssa-threadbackward.c (revision 239164) +++ gcc/tree-ssa-threadbackward.c (working copy) @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. #include "tree-pass.h" #include "gimple-ssa.h" #include "tree-phinodes.h" +#include "cfghooks.h" static int max_threaded_paths; @@ -206,8 +207,9 @@ profitable_jump_thread_path (vec<basic_b /* Note that if both NAME and DST are anonymous SSA_NAMEs, then we do not have enough information to consider them associated. */ - if ((SSA_NAME_VAR (dst) != SSA_NAME_VAR (name) - || !SSA_NAME_VAR (dst)) + if (dst != name + && (SSA_NAME_VAR (dst) != SSA_NAME_VAR (name) + || !SSA_NAME_VAR (dst)) && !virtual_operand_p (dst)) ++n_insns; } @@ -560,9 +562,13 @@ fsm_find_control_statement_thread_paths edge taken_edge = profitable_jump_thread_path (path, bbi, name, arg); if (taken_edge) { + /* If the taken edge is a loop entry avoid mashing two + loops into one with multiple latches by splitting + the edge. */ if (bb_loop_depth (taken_edge->src) - >= bb_loop_depth (taken_edge->dest)) - convert_and_register_jump_thread_path (path, taken_edge); + < bb_loop_depth (taken_edge->dest)) + split_edge (taken_edge); + convert_and_register_jump_thread_path (path, taken_edge); path->pop (); } } @@ -586,9 +592,13 @@ fsm_find_control_statement_thread_paths name, arg); if (taken_edge) { + /* If the taken edge is a loop entry avoid mashing two + loops into one with multiple latches by splitting + the edge. */ if (bb_loop_depth (taken_edge->src) - >= bb_loop_depth (taken_edge->dest)) - convert_and_register_jump_thread_path (path, taken_edge); + < bb_loop_depth (taken_edge->dest)) + split_edge (taken_edge); + convert_and_register_jump_thread_path (path, taken_edge); path->pop (); }