This fixes PR59288 - re-analyzing via SCEV after performing some loop transform is fragile - we have STMT_VINFO_LOOP_PHI_EVOLUTION_PART to avoid doing this. The following applies this also to induction.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2013-11-26 Richard Biener <rguent...@suse.de> PR tree-optimization/59288 * tree-vect-loop.c (get_initial_def_for_induction): Do not re-analyze the PHI but use STMT_VINFO_LOOP_PHI_EVOLUTION_PART. * gcc.dg/torture/pr59288.c: New testcase. Index: gcc/tree-vect-loop.c =================================================================== *** gcc/tree-vect-loop.c (revision 205380) --- gcc/tree-vect-loop.c (working copy) *************** get_initial_def_for_induction (gimple iv *** 3199,3205 **** struct loop *iv_loop; basic_block new_bb; tree new_vec, vec_init, vec_step, t; - tree access_fn; tree new_var; tree new_name; gimple init_stmt, induction_phi, new_stmt; --- 3199,3204 ---- *************** get_initial_def_for_induction (gimple iv *** 3207,3213 **** tree init_expr, step_expr; int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo); int i; - bool ok; int ncopies; tree expr; stmt_vec_info phi_info = vinfo_for_stmt (iv_phi); --- 3206,3211 ---- *************** get_initial_def_for_induction (gimple iv *** 3236,3248 **** latch_e = loop_latch_edge (iv_loop); loop_arg = PHI_ARG_DEF_FROM_EDGE (iv_phi, latch_e); ! access_fn = analyze_scalar_evolution (iv_loop, PHI_RESULT (iv_phi)); ! gcc_assert (access_fn); ! STRIP_NOPS (access_fn); ! ok = vect_is_simple_iv_evolution (iv_loop->num, access_fn, ! &init_expr, &step_expr); ! gcc_assert (ok); pe = loop_preheader_edge (iv_loop); vectype = get_vectype_for_scalar_type (TREE_TYPE (init_expr)); resvectype = get_vectype_for_scalar_type (TREE_TYPE (PHI_RESULT (iv_phi))); --- 3234,3245 ---- latch_e = loop_latch_edge (iv_loop); loop_arg = PHI_ARG_DEF_FROM_EDGE (iv_phi, latch_e); ! step_expr = STMT_VINFO_LOOP_PHI_EVOLUTION_PART (phi_info); ! gcc_assert (step_expr != NULL_TREE); ! pe = loop_preheader_edge (iv_loop); + init_expr = PHI_ARG_DEF_FROM_EDGE (iv_phi, + loop_preheader_edge (iv_loop)); vectype = get_vectype_for_scalar_type (TREE_TYPE (init_expr)); resvectype = get_vectype_for_scalar_type (TREE_TYPE (PHI_RESULT (iv_phi))); *************** get_initial_def_for_induction (gimple iv *** 3253,3258 **** --- 3250,3265 ---- gcc_assert (phi_info); gcc_assert (ncopies >= 1); + /* Convert the step to the desired type. */ + step_expr = force_gimple_operand (fold_convert (TREE_TYPE (init_expr), + step_expr), + &stmts, true, NULL_TREE); + if (stmts) + { + new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts); + gcc_assert (!new_bb); + } + /* Find the first insertion point in the BB. */ si = gsi_after_labels (bb); *************** get_initial_def_for_induction (gimple iv *** 3262,3270 **** /* iv_loop is nested in the loop to be vectorized. init_expr had already been created during vectorization of previous stmts. We obtain it from the STMT_VINFO_VEC_STMT of the defining stmt. */ ! tree iv_def = PHI_ARG_DEF_FROM_EDGE (iv_phi, ! loop_preheader_edge (iv_loop)); ! vec_init = vect_get_vec_def_for_operand (iv_def, iv_phi, NULL); /* If the initial value is not of proper type, convert it. */ if (!useless_type_conversion_p (vectype, TREE_TYPE (vec_init))) { --- 3269,3275 ---- /* iv_loop is nested in the loop to be vectorized. init_expr had already been created during vectorization of previous stmts. We obtain it from the STMT_VINFO_VEC_STMT of the defining stmt. */ ! vec_init = vect_get_vec_def_for_operand (init_expr, iv_phi, NULL); /* If the initial value is not of proper type, convert it. */ if (!useless_type_conversion_p (vectype, TREE_TYPE (vec_init))) { Index: gcc/testsuite/gcc.dg/torture/pr59288.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr59288.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr59288.c (working copy) *************** *** 0 **** --- 1,9 ---- + /* { dg-do compile } */ + + void + baz (int *d) + { + long int i, j, k; + for (i = 0, j = 0, k = 0; i < 512; i = (int) i + 1, j = (int) j + 1, k = (int) k + 3) + d[i] = j ^ (i * 3) ^ (2 * k + 2); + }