On Mon, 22 Aug 2016, Dominique d'Humières wrote: > This patch causes: > > FAIL: gfortran.dg/vect/pr69466.f90 -O (internal compiler error) > FAIL: gfortran.dg/vect/pr69466.f90 -O (test for excess errors) > with -m32. > > [Book15] f90/bug% gfc > /opt/gcc/_clean/gcc/testsuite/gfortran.dg/vect/pr69466.f90 -O2 > -ftree-vectorize -m32 -march=core-avx2 > /opt/gcc/_clean/gcc/testsuite/gfortran.dg/vect/pr69466.f90:4:0: > > subroutine foo > > internal compiler error: in slpeel_duplicate_current_defs_from_edges, at > tree-vect-loop-manip.c:750
Somehow missed that. I am testing the following. Richard. 2016-08-23 Richard Biener <rguent...@suse.de> PR tree-optimization/77286 * tree-vect-loop.c (vect_analyze_loop_form_1): Do not modify the CFG here. (vect_transform_loop): Split exit edges of loop and scalar loop if required and at the appropriate time. Index: gcc/tree-vect-loop.c =================================================================== --- gcc/tree-vect-loop.c (revision 239684) +++ gcc/tree-vect-loop.c (working copy) @@ -1486,23 +1498,14 @@ vect_analyze_loop_form_1 (struct loop *l return false; } - /* Make sure there exists a single-predecessor exit bb: */ - if (!single_pred_p (single_exit (loop)->dest)) + /* Make sure the exit is not abnormal. */ + edge e = single_exit (loop); + if (e->flags & EDGE_ABNORMAL) { - edge e = single_exit (loop); - if (!(e->flags & EDGE_ABNORMAL)) - { - split_loop_exit_edge (e); - if (dump_enabled_p ()) - dump_printf (MSG_NOTE, "split exit edge.\n"); - } - else - { - if (dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, - "not vectorized: abnormal loop exit edge.\n"); - return false; - } + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: abnormal loop exit edge.\n"); + return false; } *loop_cond = vect_get_loop_niters (loop, assumptions, number_of_iterations, @@ -6759,6 +6766,16 @@ vect_transform_loop (loop_vec_info loop_ check_profitability = true; } + /* Make sure there exists a single-predecessor exit bb. Do this before + versioning. */ + edge e = single_exit (loop); + if (! single_pred_p (e->dest)) + { + split_loop_exit_edge (e); + if (dump_enabled_p ()) + dump_printf (MSG_NOTE, "split exit edge\n"); + } + /* Version the loop first, if required, so the profitability check comes first. */ @@ -6768,6 +6785,22 @@ vect_transform_loop (loop_vec_info loop_ check_profitability = false; } + /* Make sure there exists a single-predecessor exit bb also on the + scalar loop copy. Do this after versioning but before peeling + so CFG structure is fine for both scalar and if-converted loop + to make slpeel_duplicate_current_defs_from_edges face matched + loop closed PHI nodes on the exit. */ + if (LOOP_VINFO_SCALAR_LOOP (loop_vinfo)) + { + e = single_exit (LOOP_VINFO_SCALAR_LOOP (loop_vinfo)); + if (! single_pred_p (e->dest)) + { + split_loop_exit_edge (e); + if (dump_enabled_p ()) + dump_printf (MSG_NOTE, "split exit edge of scalar loop\n"); + } + } + tree ni_name = vect_build_loop_niters (loop_vinfo); LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo) = ni_name;