[patch] Fix PR22372

Ira Rosen IRAR@il.ibm.com
Wed Oct 18 09:23:00 GMT 2006


As suggested by Richard in
http://gcc.gnu.org/ml/gcc-patches/2005-08/msg00918.html this patch changes
the creation of vectorized data-ref to avoid type mismatch.

Bootstrapped and tested on ppc-linux.

Ira

:ADDPATCH SSA (vectorizer):

ChangeLog:

      PR tree-optimization/22372
      * tree-vect-transform.c (vect_create_addr_base_for_vector_ref):
Convert
      the type of the base address.
      (vect_create_data_ref_ptr): Add an argument, type of the data-ref.
Use
      it in the data-ref pointer creation.
      (vect_init_vector): Add an argument, type of the init vector. Use it
in
      the stmt creation.
      (vect_get_vec_def_for_operand): Fix calls to vect_init_vector.
      (get_initial_def_for_reduction): Likewise.
      (vectorizable_store): Fix call to vect_create_data_ref_ptr. Use the
      correct type in stmt creation.
      (vectorizable_load): Fix calls to vect_create_data_ref_ptr.
      (vect_update_ivs_after_vectorizer): Use the correct type in stmt
      creation.

Patch:

Index: tree-vect-transform.c
===================================================================
--- tree-vect-transform.c       (revision 117455)
+++ tree-vect-transform.c       (working copy)
@@ -50,11 +50,11 @@ static bool vect_transform_stmt (tree, b
 static void vect_align_data_ref (tree);
 static tree vect_create_destination_var (tree, tree);
 static tree vect_create_data_ref_ptr
-  (tree, block_stmt_iterator *, tree, tree *, bool);
+  (tree, block_stmt_iterator *, tree, tree *, bool, tree);
 static tree vect_create_addr_base_for_vector_ref (tree, tree *, tree);
 static tree vect_get_new_vect_var (tree, enum vect_var_kind, const char
*);
 static tree vect_get_vec_def_for_operand (tree, tree, tree *);
-static tree vect_init_vector (tree, tree);
+static tree vect_init_vector (tree, tree, tree);
 static void vect_finish_stmt_generation
   (tree stmt, tree vec_stmt, block_stmt_iterator *bsi);
 static bool vect_is_simple_cond (tree, loop_vec_info);
@@ -140,15 +140,12 @@ vect_create_addr_base_for_vector_ref (tr
   struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
   tree data_ref_base = unshare_expr (DR_BASE_ADDRESS (dr));
   tree base_name = build_fold_indirect_ref (data_ref_base);
-  tree ref = DR_REF (dr);
-  tree scalar_type = TREE_TYPE (ref);
-  tree scalar_ptr_type = build_pointer_type (scalar_type);
   tree vec_stmt;
-  tree new_temp;
   tree addr_base, addr_expr;
   tree dest, new_stmt;
   tree base_offset = unshare_expr (DR_OFFSET (dr));
   tree init = unshare_expr (DR_INIT (dr));
+  tree vect_ptr_type, addr_expr2;

   /* Create base_offset */
   base_offset = size_binop (PLUS_EXPR, base_offset, init);
@@ -173,21 +170,25 @@ vect_create_addr_base_for_vector_ref (tr
   addr_base = fold_build2 (PLUS_EXPR, TREE_TYPE (data_ref_base),
data_ref_base,
                           base_offset);

+  vect_ptr_type = build_pointer_type (STMT_VINFO_VECTYPE (stmt_info));
+
   /* addr_expr = addr_base */
-  addr_expr = vect_get_new_vect_var (scalar_ptr_type, vect_pointer_var,
+  addr_expr = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var,
                                      get_name (base_name));
   add_referenced_var (addr_expr);
-  vec_stmt = build2 (MODIFY_EXPR, void_type_node, addr_expr, addr_base);
-  new_temp = make_ssa_name (addr_expr, vec_stmt);
-  TREE_OPERAND (vec_stmt, 0) = new_temp;
-  append_to_statement_list_force (vec_stmt, new_stmt_list);
+  vec_stmt = fold_convert (vect_ptr_type, addr_base);
+  addr_expr2 = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var,
+                                     get_name (base_name));
+  add_referenced_var (addr_expr2);
+  vec_stmt = force_gimple_operand (vec_stmt, &new_stmt, false,
addr_expr2);
+  append_to_statement_list_force (new_stmt, new_stmt_list);

   if (vect_print_dump_info (REPORT_DETAILS))
     {
       fprintf (vect_dump, "created ");
       print_generic_expr (vect_dump, vec_stmt, TDF_SLIM);
     }
-  return new_temp;
+  return vec_stmt;
 }


@@ -224,6 +225,7 @@ vect_align_data_ref (tree stmt)
         by the data-ref in STMT.
    4. ONLY_INIT: indicate if vp is to be updated in the loop, or remain
         pointing to the initial address.
+   5. TYPE: if not NULL indicates the required type of the data-ref

    Output:
    1. Declare a new ptr to vector_type, and have it point to the base of
the
@@ -250,7 +252,8 @@ vect_align_data_ref (tree stmt)
 static tree
 vect_create_data_ref_ptr (tree stmt,
                          block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
-                         tree offset, tree *initial_address, bool
only_init)
+                         tree offset, tree *initial_address, bool
only_init,
+                          tree type)
 {
   tree base_name;
   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
@@ -287,13 +290,14 @@ vect_create_data_ref_ptr (tree stmt,
     }

   /** (1) Create the new vector-pointer variable:  **/
-
-  vect_ptr_type = build_pointer_type (vectype);
+  if (type)
+    vect_ptr_type = build_pointer_type (type);
+  else
+    vect_ptr_type = build_pointer_type (vectype);
   vect_ptr = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var,
                                     get_name (base_name));
   add_referenced_var (vect_ptr);
-
-
+
   /** (2) Add aliasing information to the new vector-pointer:
           (The points-to info (DR_PTR_INFO) may be defined later.)  **/

@@ -328,7 +332,6 @@ vect_create_data_ref_ptr (tree stmt,
   new_bb = bsi_insert_on_edge_immediate (pe, vec_stmt);
   gcc_assert (!new_bb);

-
   /** (4) Handle the updating of the vector-pointer inside the loop: **/

   if (only_init) /* No update in loop is required.  */
@@ -402,7 +405,7 @@ vect_create_destination_var (tree scalar
    used in the vectorization of STMT.  */

 static tree
-vect_init_vector (tree stmt, tree vector_var)
+vect_init_vector (tree stmt, tree vector_var, tree vector_type)
 {
   stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
@@ -415,7 +418,7 @@ vect_init_vector (tree stmt, tree vector
   tree new_temp;
   basic_block new_bb;

-  new_var = vect_get_new_vect_var (vectype, vect_simple_var, "cst_");
+  new_var = vect_get_new_vect_var (vector_type, vect_simple_var, "cst_");
   add_referenced_var (new_var);

   init_stmt = build2 (MODIFY_EXPR, vectype, new_var, vector_var);
@@ -467,6 +470,7 @@ vect_get_vec_def_for_operand (tree op, t
   int i;
   enum vect_def_type dt;
   bool is_simple_use;
+  tree vector_type;

   if (vect_print_dump_info (REPORT_DETAILS))
     {
@@ -506,8 +510,10 @@ vect_get_vec_def_for_operand (tree op, t
           {
             t = tree_cons (NULL_TREE, op, t);
           }
-        vec_cst = build_vector (vectype, t);
-        return vect_init_vector (stmt, vec_cst);
+        vector_type = get_vectype_for_scalar_type (TREE_TYPE (op));
+        vec_cst = build_vector (vector_type, t);
+
+        return vect_init_vector (stmt, vec_cst, vector_type);
       }

     /* Case 2: operand is defined outside the loop - loop invariant.  */
@@ -526,8 +532,9 @@ vect_get_vec_def_for_operand (tree op, t
           }

        /* FIXME: use build_constructor directly.  */
-        vec_inv = build_constructor_from_list (vectype, t);
-        return vect_init_vector (stmt, vec_inv);
+        vector_type = get_vectype_for_scalar_type (TREE_TYPE (def));
+        vec_inv = build_constructor_from_list (vector_type, t);
+        return vect_init_vector (stmt, vec_inv, vector_type);
       }

     /* Case 3: operand is defined inside the loop.  */
@@ -652,6 +659,7 @@ get_initial_def_for_reduction (tree stmt
   tree vec, t = NULL_TREE;
   bool need_epilog_adjust;
   int i;
+  tree vector_type;

   gcc_assert (INTEGRAL_TYPE_P (type) || SCALAR_FLOAT_TYPE_P (type));

@@ -699,18 +707,19 @@ get_initial_def_for_reduction (tree stmt
       nelements += 1;
     }
   gcc_assert (nelements == nunits);
-
+
+  vector_type = get_vectype_for_scalar_type (TREE_TYPE (def));
   if (TREE_CODE (init_val) == INTEGER_CST || TREE_CODE (init_val) ==
REAL_CST)
-    vec = build_vector (vectype, t);
+    vec = build_vector (vector_type, t);
   else
-    vec = build_constructor_from_list (vectype, t);
+    vec = build_constructor_from_list (vector_type, t);

   if (!need_epilog_adjust)
     *scalar_def = NULL_TREE;
   else
     *scalar_def = init_val;

-  return vect_init_vector (stmt, vec);
+  return vect_init_vector (stmt, vec, vector_type);
 }


@@ -1719,11 +1728,13 @@ vectorizable_store (tree stmt, block_stm
   /* Handle def.  */
   /* FORNOW: make sure the data reference is aligned.  */
   vect_align_data_ref (stmt);
-  data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, &dummy,
false);
+  data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, &dummy,
false,
+                                       TREE_TYPE (vec_oprnd1));
   data_ref = build_fold_indirect_ref (data_ref);

   /* Arguments are ready. create the new vector stmt.  */
-  *vec_stmt = build2 (MODIFY_EXPR, vectype, data_ref, vec_oprnd1);
+  *vec_stmt = build2 (MODIFY_EXPR, TREE_TYPE (vec_oprnd1), data_ref,
+                      vec_oprnd1);
   vect_finish_stmt_generation (stmt, *vec_stmt, bsi);

   /* Copy the V_MAY_DEFS representing the aliasing of the original array
@@ -1841,7 +1852,8 @@ vectorizable_load (tree stmt, block_stmt
       */

       vec_dest = vect_create_destination_var (scalar_dest, vectype);
-      data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, &dummy,
false);
+      data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE, &dummy,
false,
+                                           NULL_TREE);
       if (aligned_access_p (dr))
         data_ref = build_fold_indirect_ref (data_ref);
       else
@@ -1885,7 +1897,7 @@ vectorizable_load (tree stmt, block_stmt
       /* <1> Create msq_init = *(floor(p1)) in the loop preheader  */
       vec_dest = vect_create_destination_var (scalar_dest, vectype);
       data_ref = vect_create_data_ref_ptr (stmt, bsi, NULL_TREE,
-                                          &init_addr, true);
+                                          &init_addr, true, NULL_TREE);
       data_ref = build1 (ALIGN_INDIRECT_REF, vectype, data_ref);
       new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref);
       new_temp = make_ssa_name (vec_dest, new_stmt);
@@ -1900,7 +1912,8 @@ vectorizable_load (tree stmt, block_stmt
       /* <2> Create lsq = *(floor(p2')) in the loop  */
       offset = size_int (TYPE_VECTOR_SUBPARTS (vectype) - 1);
       vec_dest = vect_create_destination_var (scalar_dest, vectype);
-      dataref_ptr = vect_create_data_ref_ptr (stmt, bsi, offset, &dummy,
false);
+      dataref_ptr = vect_create_data_ref_ptr (stmt, bsi, offset, &dummy,
false,
+                                              NULL_TREE);
       data_ref = build1 (ALIGN_INDIRECT_REF, vectype, dataref_ptr);
       new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref);
       new_temp = make_ssa_name (vec_dest, new_stmt);
@@ -1916,10 +1929,12 @@ vectorizable_load (tree stmt, block_stmt
          /* Create permutation mask, if required, in loop preheader.  */
          tree builtin_decl;
          params = build_tree_list (NULL_TREE, init_addr);
-         vec_dest = vect_create_destination_var (scalar_dest, vectype);
          builtin_decl = targetm.vectorize.builtin_mask_for_load ();
          new_stmt = build_function_call_expr (builtin_decl, params);
-         new_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, new_stmt);
+         vec_dest = vect_create_destination_var (scalar_dest,
+                                                 TREE_TYPE (new_stmt));
+         new_stmt = build2 (MODIFY_EXPR, TREE_TYPE (vec_dest), vec_dest,
+                            new_stmt);
          new_temp = make_ssa_name (vec_dest, new_stmt);
          TREE_OPERAND (new_stmt, 0) = new_temp;
          new_bb = bsi_insert_on_edge_immediate (pe, new_stmt);
@@ -2552,12 +2567,13 @@ vect_update_ivs_after_vectorizer (loop_v
                                                               loop->num));

       ni = build2 (PLUS_EXPR, TREE_TYPE (init_expr),
-                 build2 (MULT_EXPR, TREE_TYPE (niters),
-                      niters, step_expr), init_expr);
+                 build2 (MULT_EXPR, TREE_TYPE (init_expr),
+                        fold_convert (TREE_TYPE (init_expr), niters),
step_expr),
+                  init_expr);

       var = create_tmp_var (TREE_TYPE (init_expr), "tmp");
       add_referenced_var (var);
-
+
       ni_name = force_gimple_operand (ni, &stmt, false, var);

       /* Insert stmt into exit_bb.  */



More information about the Gcc-patches mailing list