gcc-9.0.0-alpha20180923 snapshot (r264518) ICEs when compiling the following snippet w/ -O3 (-Ofast) -fno-code-hoisting -fno-expensive-optimizations -fno-tree-ccp -fno-tree-copy-prop -fno-tree-dce -fno-tree-dominator-opts -fno-tree-forwprop -fno-tree-pre -fno-tree-scev-cprop: int kg (int fs) { int ij; unsigned int jt; for (jt = 0; jt < 1; ++jt) { ++fs; ij = fs; } return ij; } % gcc-9.0.0-alpha20180923 -O3 -fno-code-hoisting -fno-expensive-optimizations -fno-tree-ccp -fno-tree-copy-prop -fno-tree-dce -fno-tree-dominator-opts -fno-tree-forwprop -fno-tree-pre -fno-tree-scev-cprop -c kj92n7c0.c during RTL pass: expand kj92n7c0.c: In function 'kg': kj92n7c0.c:2:1: internal compiler error: in expand_LOOP_VECTORIZED, at internal-fn.c:2431 2 | kg (int fs) | ^~ 0x625c4a expand_LOOP_VECTORIZED /var/tmp/portage/sys-devel/gcc-9.0.0_alpha20180923/work/gcc-9-20180923/gcc/internal-fn.c:2431 0x89c1d7 expand_call_stmt /var/tmp/portage/sys-devel/gcc-9.0.0_alpha20180923/work/gcc-9-20180923/gcc/cfgexpand.c:2603 0x89c1d7 expand_gimple_stmt_1 /var/tmp/portage/sys-devel/gcc-9.0.0_alpha20180923/work/gcc-9-20180923/gcc/cfgexpand.c:3582 0x89c1d7 expand_gimple_stmt /var/tmp/portage/sys-devel/gcc-9.0.0_alpha20180923/work/gcc-9-20180923/gcc/cfgexpand.c:3741 0x89d1e1 expand_gimple_basic_block /var/tmp/portage/sys-devel/gcc-9.0.0_alpha20180923/work/gcc-9-20180923/gcc/cfgexpand.c:5777 0x8a1fe7 execute /var/tmp/portage/sys-devel/gcc-9.0.0_alpha20180923/work/gcc-9-20180923/gcc/cfgexpand.c:6382
Started with r242550, but maybe it just exposed a latent bug?
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.
The later one has a nicer testcase (plain -O3) and I've fixed it there. *** This bug has been marked as a duplicate of bug 89247 ***