https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87446
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|--- |7.4 --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- OK, so the issue is that there's a missed CFG cleanup run somewhere (eventually done by one of the passes you disable). We have # j = PHI<1> if (j == 0) loop! else loop exit and we happily if-convert single-argument PHIs (boo). if-conversion then will do the CFG cleanup and that scraps the fallback loop while the if-converted loop now looks like j = 1; if (j == 0) .... which CFG cleanup doesn't "handle". -> Kaboom. I'd say "doctor it hurts", but of course we should cleanup the CFG properly. This time the offender is VRP which performs jump-threading and then CFG cleanup but with SSA not updated. This then runs into gimple_can_merge_blocks_p (a=<basic_block 0x7ffff68986e8 (7)>, b=<basic_block 0x7ffff6898340 (4)>) at /tmp/trunk/gcc/tree-cfg.c:1883 1939 for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi); 1940 gsi_next (&gsi)) 1941 { 1942 gphi *phi = gsi.phi (); 1943 /* Technically only new names matter. */ 1944 if (name_registered_for_update_p (PHI_RESULT (phi))) 1945 return false; 1946 } and so not merging two blocks which would propagate out the single-arg PHI. I also believe the comment is wrong and we cannot propagate the PHI out. But we could in theory simply create a copy (which of course wouldn't solve the issue at hand). So one solution might be to force a phi-only-cprop pass before tree-if-conversion but then if you disable that manually you're screwed again ;) Or try re-organizing TODO processing to "interleave" update-SSA and cleanup-CFG. We basically need cleanup_control_flow_pre () be performed first, then update-SSA if required and then continue. static void execute_function_todo (function *fn, void *data) { bool from_ipa_pass = (cfun == NULL); unsigned int flags = (size_t)data; flags &= ~fn->last_verified; if (!flags) return; push_cfun (fn); /* Always cleanup the CFG before trying to update SSA. */ if (flags & TODO_cleanup_cfg) { cleanup_tree_cfg (); ... if (flags & TODO_update_ssa_any) { unsigned update_flags = flags & TODO_update_ssa_any; update_ssa (update_flags); anyhow this seems low-priority and certainly I don't think CFG cleanup (or loop fixup) should in any way be forced to kill LOOP_VECTORIZED IFN calls.