On Fri, 5 Aug 2016, Richard Biener wrote: > > 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.
Ok, so that re-introduces the c-c++-common/ubsan/pr71403-2.c miscompile where we mash two loops retaining a bogus loop->nb_iterations_upper_bound. I think those two testcases show that it should be the dominance relation between the entered loop header and the threaded path that decides whether we can thread or not -- the path may not become another latch of this loop. I can't seem to figure out a correct condition for this based on the threading path but the following works (maybe by accident as I only have those two testcases): 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; @@ -560,6 +562,14 @@ 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. This only works if that block won't become + a latch of this loop. */ + if ((bb_loop_depth (taken_edge->src) + < bb_loop_depth (taken_edge->dest)) + && ! single_succ_p (bbi)) + split_edge (taken_edge); if (bb_loop_depth (taken_edge->src) >= bb_loop_depth (taken_edge->dest)) convert_and_register_jump_thread_path (path, taken_edge); note you need the PR72772 fix to trigger all this. Any idea? Thanks, Richard. > 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 (); > } > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)