[Bug rtl-optimization/87446] [7/8/9 Regression] ICE in expand_LOOP_VECTORIZED, at internal-fn.c:2431
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Sep 27 08:34:00 GMT 2018
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.
More information about the Gcc-bugs
mailing list