[PATCH] Fix PR46723

Ira Rosen IRAR@il.ibm.com
Thu Dec 2 13:34:00 GMT 2010



Richard Guenther <rguenther@suse.de> wrote on 02/12/2010 02:32:53 PM:

> This tries to fix PR46723 where vectorizer analysis of induction
> fails to recongize the effect that peeling does on SCEV analysis
> and the result doesn't end up being properly analyzable.  The
> fix here is to treat sign changing conversions like we do at
> copy statements - use a vector VIEW_CONVERT_EXPR at uses.
>
> The patch doesn't touch the analysis part which makes the patch
eventually
> more suitable for backporting to 4.5.  But in principle we can
> ignore this kind of conversions at analysis time as well.

It's only a matter of adding STRIP_NOPS in the analysis (in
vect_analyze_scalar_cycles_1), right?
Maybe we can do that for 4.6 only?

>
> Bootstrapped and tested on x86_64-unknown-linux-gnu, I also made
> sure we can still build SPEC 2k6 with this patch applied.  Ok for
> trunk?

OK with me otherwise.

Thanks,
Ira

>
> Thanks,
> Richard.
>
> 2010-12-01  Richard Guenther  <rguenther@suse.de>
>
>    PR tree-optimization/46723
>    * tree-vect-loop.c (get_initial_def_for_induction): Strip
>    conversions from the induction evolution and apply it to
>    the result instead.
>    * tree-vect-stmts.c (vect_get_vec_def_for_operand): Handle
>    assigns for induction defs.
>
>    * gcc.dg/torture/pr46723.c: New testcase.
>
> Index: gcc/tree-vect-loop.c
> ===================================================================
> *** gcc/tree-vect-loop.c   (revision 167325)
> --- gcc/tree-vect-loop.c   (working copy)
> *************** get_initial_def_for_induction (gimple iv
> *** 2594,2600 ****
>     stmt_vec_info stmt_vinfo = vinfo_for_stmt (iv_phi);
>     loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
>     struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
> !   tree scalar_type = TREE_TYPE (gimple_phi_result (iv_phi));
>     tree vectype;
>     int nunits;
>     edge pe = loop_preheader_edge (loop);
> --- 2594,2600 ----
>     stmt_vec_info stmt_vinfo = vinfo_for_stmt (iv_phi);
>     loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
>     struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
> !   tree scalar_type;
>     tree vectype;
>     int nunits;
>     edge pe = loop_preheader_edge (loop);
> *************** get_initial_def_for_induction (gimple iv
> *** 2623,2646 ****
>     gimple_stmt_iterator si;
>     basic_block bb = gimple_bb (iv_phi);
>     tree stepvectype;
> !
> !   vectype = get_vectype_for_scalar_type (scalar_type);
> !   gcc_assert (vectype);
> !   nunits = TYPE_VECTOR_SUBPARTS (vectype);
> !   ncopies = vf / nunits;
> !
> !   gcc_assert (phi_info);
> !   gcc_assert (ncopies >= 1);
> !
> !   /* Find the first insertion point in the BB.  */
> !   si = gsi_after_labels (bb);
> !
> !   if (INTEGRAL_TYPE_P (scalar_type))
> !     step_expr = build_int_cst (scalar_type, 0);
> !   else if (POINTER_TYPE_P (scalar_type))
> !     step_expr = size_zero_node;
> !   else
> !     step_expr = build_real (scalar_type, dconst0);
>
>     /* Is phi in an inner-loop, while vectorizing an enclosing
outer-loop?  */
>     if (nested_in_vect_loop_p (loop, iv_phi))
> --- 2623,2629 ----
>     gimple_stmt_iterator si;
>     basic_block bb = gimple_bb (iv_phi);
>     tree stepvectype;
> !   tree resvectype;
>
>     /* Is phi in an inner-loop, while vectorizing an enclosing
outer-loop?  */
>     if (nested_in_vect_loop_p (loop, iv_phi))
> *************** get_initial_def_for_induction (gimple iv
> *** 2657,2667 ****
> --- 2640,2664 ----
>
>     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);
>
> +   scalar_type = TREE_TYPE (init_expr);
> +   vectype = get_vectype_for_scalar_type (scalar_type);
> +   resvectype = get_vectype_for_scalar_type (TREE_TYPE (PHI_RESULT
> (iv_phi)));
> +   gcc_assert (vectype);
> +   nunits = TYPE_VECTOR_SUBPARTS (vectype);
> +   ncopies = vf / nunits;
> +
> +   gcc_assert (phi_info);
> +   gcc_assert (ncopies >= 1);
> +
> +   /* Find the first insertion point in the BB.  */
> +   si = gsi_after_labels (bb);
> +
>     /* Create the vector that holds the initial_value of the induction.
*/
>     if (nested_in_vect_loop)
>       {
> *************** get_initial_def_for_induction (gimple iv
> *** 2687,2693 ****
>      }
>
>         t = NULL_TREE;
> !       t = tree_cons (NULL_TREE, init_expr, t);
>         for (i = 1; i < nunits; i++)
>      {
>        /* Create: new_name_i = new_name + step_expr  */
> --- 2684,2690 ----
>      }
>
>         t = NULL_TREE;
> !       t = tree_cons (NULL_TREE, new_name, t);
>         for (i = 1; i < nunits; i++)
>      {
>        /* Create: new_name_i = new_name + step_expr  */
> *************** get_initial_def_for_induction (gimple iv
> *** 2802,2807 ****
> --- 2799,2817 ----
>        gimple_assign_set_lhs (new_stmt, vec_def);
>
>        gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
> +      if (!useless_type_conversion_p (resvectype, vectype))
> +        {
> +          new_stmt = gimple_build_assign_with_ops
> +         (VIEW_CONVERT_EXPR,
> +          vect_get_new_vect_var (resvectype, vect_simple_var,
> +                  "vec_iv_"),
> +          build1 (VIEW_CONVERT_EXPR, resvectype,
> +             gimple_assign_lhs (new_stmt)), NULL_TREE);
> +          gimple_assign_set_lhs (new_stmt,
> +                  make_ssa_name
> +                    (gimple_assign_lhs (new_stmt), new_stmt));
> +          gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
> +        }
>        set_vinfo_for_stmt (new_stmt,
>                  new_stmt_vec_info (new_stmt, loop_vinfo, NULL));
>        STMT_VINFO_RELATED_STMT (prev_stmt_vinfo) = new_stmt;
> *************** get_initial_def_for_induction (gimple iv
> *** 2849,2854 ****
> --- 2859,2876 ----
>       }
>
>     STMT_VINFO_VEC_STMT (phi_info) = induction_phi;
> +   if (!useless_type_conversion_p (resvectype, vectype))
> +     {
> +       new_stmt = gimple_build_assign_with_ops
> +     (VIEW_CONVERT_EXPR,
> +      vect_get_new_vect_var (resvectype, vect_simple_var, "vec_iv_"),
> +      build1 (VIEW_CONVERT_EXPR, resvectype, induc_def), NULL_TREE);
> +       induc_def = make_ssa_name (gimple_assign_lhs (new_stmt),
new_stmt);
> +       gimple_assign_set_lhs (new_stmt, induc_def);
> +       si = gsi_start_bb (bb);
> +       gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
> +     }
> +
>     return induc_def;
>   }
>
> Index: gcc/tree-vect-stmts.c
> ===================================================================
> *** gcc/tree-vect-stmts.c   (revision 167325)
> --- gcc/tree-vect-stmts.c   (working copy)
> *************** vect_get_vec_def_for_operand (tree op, g
> *** 1102,1109 ****
>           /* Get the def from the vectorized stmt.  */
>           def_stmt_info = vinfo_for_stmt (def_stmt);
>           vec_stmt = STMT_VINFO_VEC_STMT (def_stmt_info);
> !    gcc_assert (vec_stmt && gimple_code (vec_stmt) == GIMPLE_PHI);
> !         vec_oprnd = PHI_RESULT (vec_stmt);
>           return vec_oprnd;
>         }
>
> --- 1102,1111 ----
>           /* Get the def from the vectorized stmt.  */
>           def_stmt_info = vinfo_for_stmt (def_stmt);
>           vec_stmt = STMT_VINFO_VEC_STMT (def_stmt_info);
> !    if (gimple_code (vec_stmt) == GIMPLE_PHI)
> !      vec_oprnd = PHI_RESULT (vec_stmt);
> !    else
> !      vec_oprnd = gimple_get_lhs (vec_stmt);
>           return vec_oprnd;
>         }
>
> Index: gcc/testsuite/gcc.dg/torture/pr46723.c
> ===================================================================
> *** gcc/testsuite/gcc.dg/torture/pr46723.c   (revision 0)
> --- gcc/testsuite/gcc.dg/torture/pr46723.c   (revision 0)
> ***************
> *** 0 ****
> --- 1,10 ----
> + /* { dg-do compile } */
> +
> + short *m;
> + void test()
> + {
> +   short x = 128;
> +   unsigned int i;
> +   for (i = 0; i < 128; ++i, x = (unsigned short)x + 1)
> +     m[i] = x;
> + }



More information about the Gcc-patches mailing list