This fixes PR59164 - a mismatch during vectorizer analysis and transform. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk sofar.
Richard. 2013-11-19 Richard Biener <rguent...@suse.de> PR tree-optimization/59164 * tree-vect-loop-manip.c (vect_update_ivs_after_vectorizer): Uncomment assert. * tree-vect-loop.c (vect_analyze_loop_operations): Adjust check whether we can create an epilogue loop to reflect the cases where we create one. * gcc.dg/torture/pr59164.c: New testcase. Index: gcc/tree-vect-loop-manip.c =================================================================== *** gcc/tree-vect-loop-manip.c (revision 205009) --- gcc/tree-vect-loop-manip.c (working copy) *************** vect_update_ivs_after_vectorizer (loop_v *** 1672,1678 **** gimple_stmt_iterator gsi, gsi1; basic_block update_bb = update_e->dest; ! /* gcc_assert (vect_can_advance_ivs_p (loop_vinfo)); */ /* Make sure there exists a single-predecessor exit bb: */ gcc_assert (single_pred_p (exit_bb)); --- 1667,1673 ---- gimple_stmt_iterator gsi, gsi1; basic_block update_bb = update_e->dest; ! gcc_checking_assert (vect_can_advance_ivs_p (loop_vinfo)); /* Make sure there exists a single-predecessor exit bb: */ gcc_assert (single_pred_p (exit_bb)); Index: gcc/tree-vect-loop.c =================================================================== *** gcc/tree-vect-loop.c (revision 205009) --- gcc/tree-vect-loop.c (working copy) *************** vect_analyze_loop_operations (loop_vec_i *** 1586,1609 **** return false; } ! if (LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo) || ((int) tree_ctz (LOOP_VINFO_NITERS (loop_vinfo)) < exact_log2 (vectorization_factor))) { if (dump_enabled_p ()) ! dump_printf_loc (MSG_NOTE, vect_location, "epilog loop required.\n"); ! if (!vect_can_advance_ivs_p (loop_vinfo)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, ! "not vectorized: can't create epilog loop 1.\n"); ! return false; ! } ! if (!slpeel_can_duplicate_loop_p (loop, single_exit (loop))) ! { ! if (dump_enabled_p ()) ! dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, ! "not vectorized: can't create epilog loop 2.\n"); return false; } } --- 1586,1604 ---- return false; } ! if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo) || ((int) tree_ctz (LOOP_VINFO_NITERS (loop_vinfo)) < exact_log2 (vectorization_factor))) { if (dump_enabled_p ()) ! dump_printf_loc (MSG_NOTE, vect_location, "epilog loop required\n"); ! if (!vect_can_advance_ivs_p (loop_vinfo) ! || !slpeel_can_duplicate_loop_p (loop, single_exit (loop))) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, ! "not vectorized: can't create required " ! "epilog loop\n"); return false; } } Index: gcc/testsuite/gcc.dg/torture/pr59164.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr59164.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr59164.c (working copy) *************** *** 0 **** --- 1,21 ---- + /* { dg-do compile } */ + + int a, d, e; + long b[10]; + int c[10][8]; + + int fn1(p1) + { + return 1 >> p1; + } + + void fn2(void) + { + int f; + for (a=1; a <= 4; a++) + { + f = fn1(0 < c[a][0]); + if (f || d) + e = b[a] = 1; + } + }