http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58377
--- Comment #11 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to davidxl from comment #10) > When an incoming edge to a phi is a critical edge, the 'use BB' for the phi > arg should be in the split BB of the edge. Pushing the use into either the > Source BB or the dest BB will result in extending the 'use' falsely in more > BBs. In this case, simply use the PHI's BB won't solve the problem, as > there is an incoming path introduced not guarded by if (iftmp.1_3 != 0) > > I don't see a good way to fix it unless splitting the edge. I wondered if we can make is_use_properly_guarded take the case of a use on an edge into account by simply injecting the predicate at the end of the predecessor into the list of predicates found by find_predicates. Hmm, but I see it's not a simple list of predicates ... I wonder what effect splitting critical edges somewhere before late uninit has on following optimization passes and RTL expansion and its out-of-SSA process (though the next cfgcleanup pass will unsplit the edges again, which is at latest pass_cleanup_cfg_post_optimizing) But I can confirm that the testcase is fixed with Index: gcc/passes.c =================================================================== --- gcc/passes.c (revision 202445) +++ gcc/passes.c (working copy) @@ -1543,6 +1543,7 @@ init_optimization_passes (void) /* ??? We do want some kind of loop invariant motion, but we possibly need to adjust LIM to be more friendly towards preserving accurate debug information here. */ + NEXT_PASS (pass_split_crit_edges); NEXT_PASS (pass_late_warn_uninitialized); NEXT_PASS (pass_uncprop); NEXT_PASS (pass_local_pure_const); which does this just for -Og. I'm seriously considering this, splitting critical edges is cheap.