[backport from gcc-4.7.1 r187770 ] gcc/ 2012-05-22 Richard Guenther PR tree-optimization/53408 * tree-vect-loop.c (vectorizable_induction): Properly check the restriction that we cannot handle induction results from the inner loop outside of the outer loop. gcc/testsuite/ 2012-05-22 Richard Guenther PR tree-optimization/53408 * gcc.dg/torture/pr53408.c: New testcase. --- gcc-4.6.3/gcc/testsuite/gcc.dg/torture/pr53408.c.~1~ 1970-01-01 01:00:00.000000000 +0100 +++ gcc-4.6.3/gcc/testsuite/gcc.dg/torture/pr53408.c 2012-06-09 22:42:56.000000000 +0200 @@ -0,0 +1,20 @@ +/* { dg-do compile } */ + +int a, b, c, d, e; +void +fn1 () +{ + int f, g; + char h = 0; + b = 0; + for (; b < 32; b++) + { + g = h > e ? h : h << 1; + f = g && a ? 0 : 1; + h = 1; + for (; h > 0; h = h + 1) + c = 0 < h | f; + } + if (h) + d = 0; +} --- gcc-4.6.3/gcc/tree-vect-loop.c.~1~ 2011-06-04 11:20:00.000000000 +0200 +++ gcc-4.6.3/gcc/tree-vect-loop.c 2012-06-09 22:42:56.000000000 +0200 @@ -4545,12 +4545,46 @@ vectorizable_induction (gimple phi, gimp tree vec_def; gcc_assert (ncopies >= 1); - /* FORNOW. This restriction should be relaxed. */ - if (nested_in_vect_loop_p (loop, phi) && ncopies > 1) + /* FORNOW. These restrictions should be relaxed. */ + if (nested_in_vect_loop_p (loop, phi)) { - if (vect_print_dump_info (REPORT_DETAILS)) - fprintf (vect_dump, "multiple types in nested loop."); - return false; + imm_use_iterator imm_iter; + use_operand_p use_p; + gimple exit_phi; + edge latch_e; + tree loop_arg; + + if (ncopies > 1) + { + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "multiple types in nested loop."); + return false; + } + + exit_phi = NULL; + latch_e = loop_latch_edge (loop->inner); + loop_arg = PHI_ARG_DEF_FROM_EDGE (phi, latch_e); + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, loop_arg) + { + if (!flow_bb_inside_loop_p (loop->inner, + gimple_bb (USE_STMT (use_p)))) + { + exit_phi = USE_STMT (use_p); + break; + } + } + if (exit_phi) + { + stmt_vec_info exit_phi_vinfo = vinfo_for_stmt (exit_phi); + if (!(STMT_VINFO_RELEVANT_P (exit_phi_vinfo) + && !STMT_VINFO_LIVE_P (exit_phi_vinfo))) + { + if (vect_print_dump_info (REPORT_DETAILS)) + fprintf (vect_dump, "inner-loop induction only used outside " + "of the outer vectorized loop."); + return false; + } + } } if (!STMT_VINFO_RELEVANT_P (stmt_info))