I am testing the following patch to fix the g++.dg/pr80481.C FAIL on x86_64. Copying of the loop force_vectorize flag caused the epilogue loops no longer be unrolled because the vectorizer fails to unset the force_vectorize flag after copying the loop causing the unroller to not touch it. This skewed the testcase enough to cause reg-reg moves to re-appear (the testcase is for a IRA issue).
Bootstrap and regtest running on x86_64-unknown-linux-gnu. Richard. 2019-03-11 Richard Biener <rguent...@suse.de> PR tree-optimization/89649 * tree-vectorizer.h (vect_loop_versioning): Adjust prototype. * tree-vect-loop-manip.c (vect_do_peeling): Unset force_vectorize on the prolog and epilog loops. (vect_loop_versioning): Return copy of loop. * tree-vect-loop.c (vect_transform_loop): Unset force_vectorize on the non-vectorized version of the loop. Index: gcc/tree-vectorizer.h =================================================================== --- gcc/tree-vectorizer.h (revision 269569) +++ gcc/tree-vectorizer.h (working copy) @@ -1449,8 +1449,8 @@ extern void vect_set_loop_condition (str extern bool slpeel_can_duplicate_loop_p (const struct loop *, const_edge); struct loop *slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *, struct loop *, edge); -extern void vect_loop_versioning (loop_vec_info, unsigned int, bool, - poly_uint64); +struct loop *vect_loop_versioning (loop_vec_info, unsigned int, bool, + poly_uint64); extern struct loop *vect_do_peeling (loop_vec_info, tree, tree, tree *, tree *, tree *, int, bool, bool); extern void vect_prepare_for_masked_peels (loop_vec_info); Index: gcc/tree-vect-loop-manip.c =================================================================== --- gcc/tree-vect-loop-manip.c (revision 269569) +++ gcc/tree-vect-loop-manip.c (working copy) @@ -2542,6 +2543,7 @@ vect_do_peeling (loop_vec_info loop_vinf "slpeel_tree_duplicate_loop_to_edge_cfg failed.\n"); gcc_unreachable (); } + prolog->force_vectorize = false; slpeel_update_phi_nodes_for_loops (loop_vinfo, prolog, loop, true); first_loop = prolog; reset_original_copy_tables (); @@ -2612,6 +2614,7 @@ vect_do_peeling (loop_vec_info loop_vinf "slpeel_tree_duplicate_loop_to_edge_cfg failed.\n"); gcc_unreachable (); } + epilog->force_vectorize = false; slpeel_update_phi_nodes_for_loops (loop_vinfo, loop, epilog, false); /* Scalar version loop may be preferred. In this case, add guard @@ -2984,7 +2987,7 @@ vect_create_cond_for_alias_checks (loop_ The versioning precondition(s) are placed in *COND_EXPR and *COND_EXPR_STMT_LIST. */ -void +struct loop * vect_loop_versioning (loop_vec_info loop_vinfo, unsigned int th, bool check_profitability, poly_uint64 versioning_threshold) @@ -3154,4 +3157,6 @@ vect_loop_versioning (loop_vec_info loop GSI_SAME_STMT); } update_ssa (TODO_update_ssa); + + return nloop; } Index: gcc/tree-vect-loop.c =================================================================== --- gcc/tree-vect-loop.c (revision 269569) +++ gcc/tree-vect-loop.c (working copy) @@ -8201,8 +8201,10 @@ vect_transform_loop (loop_vec_info loop_ versioning_threshold); check_profitability = false; } - vect_loop_versioning (loop_vinfo, th, check_profitability, - versioning_threshold); + struct loop *sloop + = vect_loop_versioning (loop_vinfo, th, check_profitability, + versioning_threshold); + sloop->force_vectorize = false; check_profitability = false; }