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);
+ }

Reply via email to