Currently for initial values for inductions the vectorizer generates

  stmp_var_.3_2 = 0 + 1;
  stmp_var_.3_19 = stmp_var_.3_2 + 1;
  stmp_var_.3_20 = stmp_var_.3_19 + 1;
  vect_cst_.4_21 = {0, stmp_var_.3_2, stmp_var_.3_19, stmp_var_.3_20};

instead of properly folding elements and eventually generate a
vector constant directly.  At the moment this is only cleaned up
by VRP later (DOM doesn't fold stmp_var_.3_2 = 0 + 1 because it
doesn't change ...).

Fixed by instead creating

  vect_cst_.4_2 = { 0, 1, 2, 3 };

in the vectorizer.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2013-04-11  Richard Biener  <rguent...@suse.de>

        * tree-vect-loop.c (get_initial_def_for_induction): Properly
        generate vector constants.

Index: gcc/tree-vect-loop.c
===================================================================
*** gcc/tree-vect-loop.c        (revision 197761)
--- gcc/tree-vect-loop.c        (working copy)
*************** get_initial_def_for_induction (gimple iv
*** 3226,3255 ****
        }
  
        vec_alloc (v, nunits);
        CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, new_name);
        for (i = 1; i < nunits; i++)
        {
          /* Create: new_name_i = new_name + step_expr  */
          enum tree_code code = POINTER_TYPE_P (scalar_type)
                                ? POINTER_PLUS_EXPR : PLUS_EXPR;
!         init_stmt = gimple_build_assign_with_ops (code, new_var,
!                                                   new_name, step_expr);
!         new_name = make_ssa_name (new_var, init_stmt);
!         gimple_assign_set_lhs (init_stmt, new_name);
! 
!         new_bb = gsi_insert_on_edge_immediate (pe, init_stmt);
!         gcc_assert (!new_bb);
! 
!         if (dump_enabled_p ())
            {
!             dump_printf_loc (MSG_NOTE, vect_location,
!                              "created new init_stmt: ");
!             dump_gimple_stmt (MSG_NOTE, TDF_SLIM, init_stmt, 0);
            }
          CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, new_name);
        }
        /* Create a vector from [new_name_0, new_name_1, ..., 
new_name_nunits-1]  */
!       new_vec = build_constructor (vectype, v);
        vec_init = vect_init_vector (iv_phi, new_vec, vectype, NULL);
      }
  
--- 3226,3261 ----
        }
  
        vec_alloc (v, nunits);
+       bool constant_p = is_gimple_min_invariant (new_name);
        CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, new_name);
        for (i = 1; i < nunits; i++)
        {
          /* Create: new_name_i = new_name + step_expr  */
          enum tree_code code = POINTER_TYPE_P (scalar_type)
                                ? POINTER_PLUS_EXPR : PLUS_EXPR;
!         new_name = fold_build2 (code, scalar_type, new_name, step_expr);
!         if (!is_gimple_min_invariant (new_name))
            {
!             init_stmt = gimple_build_assign (new_var, new_name);
!             new_name = make_ssa_name (new_var, init_stmt);
!             gimple_assign_set_lhs (init_stmt, new_name);
!             new_bb = gsi_insert_on_edge_immediate (pe, init_stmt);
!             gcc_assert (!new_bb);
!             if (dump_enabled_p ())
!               {
!                 dump_printf_loc (MSG_NOTE, vect_location,
!                                  "created new init_stmt: ");
!                 dump_gimple_stmt (MSG_NOTE, TDF_SLIM, init_stmt, 0);
!               }
!             constant_p = false;
            }
          CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, new_name);
        }
        /* Create a vector from [new_name_0, new_name_1, ..., 
new_name_nunits-1]  */
!       if (constant_p)
!       new_vec = build_vector_from_ctor (vectype, v);
!       else
!       new_vec = build_constructor (vectype, v);
        vec_init = vect_init_vector (iv_phi, new_vec, vectype, NULL);
      }
  

Reply via email to