diff options
author | Richard Biener <rguenther@suse.de> | 2019-10-30 13:52:27 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2019-10-30 13:52:27 +0000 |
commit | b81f2dafdbd2c5aa49213b35dc12d4610834e39e (patch) | |
tree | b06a85d760253f856e8043dab8a3fa8b7e3e5640 /gcc/tree-vect-loop-manip.c | |
parent | 095578b5bc9f2ff72785ff14626c6a803c973176 (diff) | |
download | gcc-b81f2dafdbd2c5aa49213b35dc12d4610834e39e.zip gcc-b81f2dafdbd2c5aa49213b35dc12d4610834e39e.tar.gz gcc-b81f2dafdbd2c5aa49213b35dc12d4610834e39e.tar.bz2 |
re PR tree-optimization/92275 (ICE: error: definition in block 11 does not dominate use in block 15 since r277566)
2019-10-30 Richard Biener <rguenther@suse.de>
PR tree-optimization/92275
* tree-vect-loop-manip.c (slpeel_update_phi_nodes_for_loops):
Copy all loop-closed PHIs.
* gcc.dg/torture/pr92275.c: New testcase.
From-SVN: r277621
Diffstat (limited to 'gcc/tree-vect-loop-manip.c')
-rw-r--r-- | gcc/tree-vect-loop-manip.c | 69 |
1 files changed, 46 insertions, 23 deletions
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index dffb40e..1fbcaf2 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -2004,6 +2004,29 @@ vect_gen_vector_loop_niters_mult_vf (loop_vec_info loop_vinfo, *niters_vector_mult_vf_ptr = niters_vector_mult_vf; } +/* LCSSA_PHI is a lcssa phi of EPILOG loop which is copied from LOOP, + this function searches for the corresponding lcssa phi node in exit + bb of LOOP. If it is found, return the phi result; otherwise return + NULL. */ + +static tree +find_guard_arg (class loop *loop, class loop *epilog ATTRIBUTE_UNUSED, + gphi *lcssa_phi) +{ + gphi_iterator gsi; + edge e = single_exit (loop); + + gcc_assert (single_pred_p (e->dest)); + for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gphi *phi = gsi.phi (); + if (operand_equal_p (PHI_ARG_DEF (phi, 0), + PHI_ARG_DEF (lcssa_phi, 0), 0)) + return PHI_RESULT (phi); + } + return NULL_TREE; +} + /* Function slpeel_tree_duplicate_loop_to_edge_cfg duplciates FIRST/SECOND from SECOND/FIRST and puts it at the original loop's preheader/exit edge, the two loops are arranged as below: @@ -2091,6 +2114,29 @@ slpeel_update_phi_nodes_for_loops (loop_vec_info loop_vinfo, incoming edge. */ adjust_phi_and_debug_stmts (update_phi, second_preheader_e, arg); } + + /* For epilogue peeling we have to make sure to copy all LC PHIs + for correct vectorization of live stmts. */ + if (loop == first) + { + basic_block orig_exit = single_exit (second)->dest; + for (gsi_orig = gsi_start_phis (orig_exit); + !gsi_end_p (gsi_orig); gsi_next (&gsi_orig)) + { + gphi *orig_phi = gsi_orig.phi (); + tree orig_arg = PHI_ARG_DEF (orig_phi, 0); + if (TREE_CODE (orig_arg) != SSA_NAME || virtual_operand_p (orig_arg)) + continue; + + /* Already created in the above loop. */ + if (find_guard_arg (first, second, orig_phi)) + continue; + + tree new_res = copy_ssa_name (orig_arg); + gphi *lcphi = create_phi_node (new_res, between_bb); + add_phi_arg (lcphi, orig_arg, single_exit (first), UNKNOWN_LOCATION); + } + } } /* Function slpeel_add_loop_guard adds guard skipping from the beginning @@ -2175,29 +2221,6 @@ slpeel_update_phi_nodes_for_guard1 (class loop *skip_loop, } } -/* LCSSA_PHI is a lcssa phi of EPILOG loop which is copied from LOOP, - this function searches for the corresponding lcssa phi node in exit - bb of LOOP. If it is found, return the phi result; otherwise return - NULL. */ - -static tree -find_guard_arg (class loop *loop, class loop *epilog ATTRIBUTE_UNUSED, - gphi *lcssa_phi) -{ - gphi_iterator gsi; - edge e = single_exit (loop); - - gcc_assert (single_pred_p (e->dest)); - for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gphi *phi = gsi.phi (); - if (operand_equal_p (PHI_ARG_DEF (phi, 0), - PHI_ARG_DEF (lcssa_phi, 0), 0)) - return PHI_RESULT (phi); - } - return NULL_TREE; -} - /* LOOP and EPILOG are two consecutive loops in CFG and EPILOG is copied from LOOP. Function slpeel_add_loop_guard adds guard skipping from a point between the two loops to the end of EPILOG. Edges GUARD_EDGE |