This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/69466] [6 Regression] ICE: Invalid PHI argument after vectorization (on -O2)
- From: "rguenth at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 27 Jan 2016 11:09:40 +0000
- Subject: [Bug tree-optimization/69466] [6 Regression] ICE: Invalid PHI argument after vectorization (on -O2)
- Auto-submitted: auto-generated
- References: <bug-69466-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69466
--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
Ok, it doesn't fix it, it somehow just makes -fno-vect-cost-model necessary.
We still split the edge, but later in vect_loop_versioning then, so the reason
for the bug is still the same - we're looking at forwarder edge PHIs.
OTOH the values there should be ok to use. We're ICEing with the 2nd peeling
now.
So the reason for the mismatch is that when split-edge comes along splitting
<bb 14>:
...
<bb 40>:
# prephitmp_112 = PHI <e.22_68(14)>
# e_lsm.38_108 = PHI <1(14)>
# e_lsm.37_100 = PHI <e.22_68(14)>
then slpeel_update_phi_nodes_for_guard2 fails to "copy" the PHI with constant
argument (which wasn't needed in the first place):
for (gsi = gsi_start_phis (update_bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
tree new_res;
update_phi = gsi.phi ();
orig_phi = update_phi;
orig_def = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
/* This loop-closed-phi actually doesn't represent a use
out of the loop - the phi arg is a constant. */
if (TREE_CODE (orig_def) != SSA_NAME)
continue;
this later confuses the current-def-setting code. This means the circumstances
are somewhat "controlled" and thus the following fix "works". Of course it
makes the whole thing even more awkward ;)
Index: tree-vect-loop-manip.c
===================================================================
--- tree-vect-loop-manip.c (revision 232867)
+++ tree-vect-loop-manip.c (working copy)
@@ -727,17 +727,26 @@ slpeel_duplicate_current_defs_from_edges
for (gsi_from = gsi_start_phis (from->dest),
gsi_to = gsi_start_phis (to->dest);
- !gsi_end_p (gsi_from) && !gsi_end_p (gsi_to);
- gsi_next (&gsi_from), gsi_next (&gsi_to))
+ !gsi_end_p (gsi_from) && !gsi_end_p (gsi_to);)
{
gimple *from_phi = gsi_stmt (gsi_from);
gimple *to_phi = gsi_stmt (gsi_to);
tree from_arg = PHI_ARG_DEF_FROM_EDGE (from_phi, from);
+ if (TREE_CODE (from_arg) != SSA_NAME)
+ {
+ gsi_next (&gsi_from);
+ continue;
+ }
tree to_arg = PHI_ARG_DEF_FROM_EDGE (to_phi, to);
- if (TREE_CODE (from_arg) == SSA_NAME
- && TREE_CODE (to_arg) == SSA_NAME
- && get_current_def (to_arg) == NULL_TREE)
+ if (TREE_CODE (to_arg) != SSA_NAME)
+ {
+ gsi_next (&gsi_to);
+ continue;
+ }
+ if (get_current_def (to_arg) == NULL_TREE)
set_current_def (to_arg, get_current_def (from_arg));
+ gsi_next (&gsi_from);
+ gsi_next (&gsi_to);
}
}