re PR tree-optimization/18536 (ICE: in emit_move_insn, at expr.c:2590 with -ftree...
authorDorit Naishlos <dorit@il.ibm.com>
Mon, 22 Nov 2004 13:55:05 +0000 (13:55 +0000)
committerDorit Nuzman <dorit@gcc.gnu.org>
Mon, 22 Nov 2004 13:55:05 +0000 (13:55 +0000)
        PR tree-opt/18536
        * tree-vectorizer.c (make_loop_iterate_ntimes): Use type of niters when
        creating iv instead of integer_type.
        (vect_build_loop_niters): Remove redundant code.
        (vect_transform_loop_bound): Removed (duplicates functionality of
        make_loop_iterate_ntimes.
        (vect_gen_niters_for_prolog_loop): Add documentation. Call
        lang_hooks.types.type_for_size to create a type of the required size.
        Use that type instead of integer_type. Remove redundant code.
        (vect_update_niters_after_peeling): Use type of niters instead of
        integer_type.
        (vect_transform_loop): Unify handling of known and unknown loop bound
        cases. Call make_loop_iterate_ntimes instead of
        vect_transform_loop_bound.

From-SVN: r91014

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr18536.c [new file with mode: 0644]
gcc/tree-vectorizer.c

index e03eea2dba53da311ba153ede4c35aab3980c2ac..df0dfa73d638e08df8977eb23e76cf859503d07d 100644 (file)
@@ -1,3 +1,20 @@
+2004-11-22  Dorit Naishlos  <dorit@il.ibm.com>
+
+       PR tree-opt/18536
+       * tree-vectorizer.c (make_loop_iterate_ntimes): Use type of niters when
+       creating iv instead of integer_type.
+       (vect_build_loop_niters): Remove redundant code.
+       (vect_transform_loop_bound): Removed (duplicates functionality of
+       make_loop_iterate_ntimes.
+       (vect_gen_niters_for_prolog_loop): Add documentation. Call
+       lang_hooks.types.type_for_size to create a type of the required size.
+       Use that type instead of integer_type. Remove redundant code.
+       (vect_update_niters_after_peeling): Use type of niters instead of
+       integer_type.
+       (vect_transform_loop): Unify handling of known and unknown loop bound
+       cases. Call make_loop_iterate_ntimes instead of 
+       vect_transform_loop_bound.
+
 2004-11-22  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR target/18217
index 3601740963151c0a8f815176894ac02255425578..3d9d53a44980988ac5bbd9e96f68ea2b89aee87e 100644 (file)
@@ -1,3 +1,8 @@
+2004-11-19  Dorit Naishlos  <dorit@il.ibm.com>
+
+       PR tree-opt/18536
+       * gcc.dg/vect/pr18536.c: New test.
+
 2004-11-22  Giovanni Bajo  <giovannibajo@gcc.gnu.org>
 
        PR c++/18354
diff --git a/gcc/testsuite/gcc.dg/vect/pr18536.c b/gcc/testsuite/gcc.dg/vect/pr18536.c
new file mode 100644 (file)
index 0000000..cd9d7bb
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+int main1 (short a, short *b)
+{
+  while (++a < 4) *b++ = 2;
+
+  return 0;
+}
+
+int main (void)
+{
+  int i = 0;
+  short x[N];
+
+  check_vect ();
+
+  main1 (0, x);
+
+  /* check results:  */
+  while (++i < 4)
+    {
+      if (x[i-1] != 2)
+        abort ();
+    }
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
index 61c22e82594452b24a57efd992d3b6dd9311e2e9..b94ffa4f25a9a1635309e99572d20bac05591f33 100644 (file)
@@ -145,6 +145,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tree-scalar-evolution.h"
 #include "tree-vectorizer.h"
 #include "tree-pass.h"
+#include "langhooks.h"
 
 
 /*************************************************************************
@@ -196,7 +197,6 @@ static bool vect_analyze_operations (loop_vec_info);
 
 /* Main code transformation functions.  */
 static void vect_transform_loop (loop_vec_info, struct loops *);
-static void vect_transform_loop_bound (loop_vec_info, tree niters);
 static bool vect_transform_stmt (tree, block_stmt_iterator *);
 static bool vectorizable_load (tree, block_stmt_iterator *, tree *);
 static bool vectorizable_store (tree, block_stmt_iterator *, tree *);
@@ -664,10 +664,12 @@ slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
   block_stmt_iterator loop_exit_bsi = bsi_last (exit_edge->src);
   tree begin_label = tree_block_label (loop->latch);
   tree exit_label = tree_block_label (loop->single_exit->dest);
+  tree init = build_int_cst (TREE_TYPE (niters), 0);
+  tree step = build_int_cst (TREE_TYPE (niters), 1);
 
   orig_cond = get_loop_exit_condition (loop);
   gcc_assert (orig_cond);
-  create_iv (integer_zero_node, integer_one_node, NULL_TREE, loop,
+  create_iv (init, step, NULL_TREE, loop,
              &loop_exit_bsi, false, &indx_before_incr, &indx_after_incr);
   
   /* CREATE_IV uses BSI_INSERT with TSI_NEW_STMT, so we want to get
@@ -2744,20 +2746,11 @@ vect_build_loop_niters (loop_vec_info loop_vinfo)
   edge pe;
   basic_block new_bb = NULL;
   struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
-  tree ni = unshare_expr (LOOP_VINFO_NITERS(loop_vinfo));
+  tree ni = unshare_expr (LOOP_VINFO_NITERS (loop_vinfo));
 
   var = create_tmp_var (TREE_TYPE (ni), "niters");
   add_referenced_tmp_var (var);
-  if (TREE_CODE (ni) == INTEGER_CST)
-    {
-      /* This case is generated when treating a known loop bound 
-        indivisible by VF. Here we cannot use force_gimple_operand.  */
-      stmt = build (MODIFY_EXPR, void_type_node, var, ni);
-      ni_name = make_ssa_name (var, stmt);
-      TREE_OPERAND (stmt, 0) = ni_name;
-    }
-  else
-    ni_name = force_gimple_operand (ni, &stmt, false, var);
+  ni_name = force_gimple_operand (ni, &stmt, false, var);
 
   pe = loop_preheader_edge (loop);
   if (stmt)
@@ -2874,45 +2867,6 @@ vect_build_symbol_bound (tree n, int vf, struct loop * loop)
 }
 
 
-/* Function vect_transform_loop_bound.
-
-   Create a new exit condition for the loop.  */
-
-static void
-vect_transform_loop_bound (loop_vec_info loop_vinfo, tree niters)
-{
-  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
-  tree orig_cond_expr;
-  HOST_WIDE_INT old_N = 0;
-  int vf;
-  tree new_loop_bound;
-  bool symbol_niters;
-  tree lb_type;
-
-  symbol_niters = !LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo);
-
-  if (!symbol_niters)
-    old_N = LOOP_VINFO_INT_NITERS (loop_vinfo);
-
-  vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
-
-  orig_cond_expr = LOOP_VINFO_EXIT_COND (loop_vinfo);
-#ifdef ENABLE_CHECKING
-  gcc_assert (orig_cond_expr);
-#endif
-
-  /* new loop exit test:  */
-  lb_type = TREE_TYPE (TREE_OPERAND (COND_EXPR_COND (orig_cond_expr), 1));
-  if (!symbol_niters)
-    new_loop_bound = 
-       fold_convert (lb_type, build_int_cst (unsigned_type_node, old_N/vf));
-  else
-    new_loop_bound = niters;
-
-  slpeel_make_loop_iterate_ntimes (loop, new_loop_bound);
-}
-
-
 /*   Function vect_update_ivs_after_vectorizer.
 
      "Advance" the induction variables of LOOP to the value they should take
@@ -3094,13 +3048,23 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio,
 /* Function vect_gen_niters_for_prolog_loop
 
    Set the number of iterations for the loop represented by LOOP_VINFO
-   to the minimum between NITERS (the original iteration count of the loop)
+   to the minimum between LOOP_NITERS (the original iteration count of the loop)
    and the misalignment of DR - the first data reference recorded in
    LOOP_VINFO_UNALIGNED_DR (LOOP_VINFO).  As a result, after the execution of 
-   this loop, the data reference DR will refer to an aligned location.  */
+   this loop, the data reference DR will refer to an aligned location.
+
+   The following computation is generated:
+
+   compute address misalignment in bytes:
+   addr_mis = addr & (vectype_size - 1)
+
+   prolog_niters = min ( LOOP_NITERS , (VF - addr_mis/elem_size)&(VF-1) )
+   
+   (elem_size = element type size; an element is the scalar element 
+       whose type is the inner type of the vectype)  */
 
 static tree 
-vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree niters)
+vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters)
 {
   struct data_reference *dr = LOOP_VINFO_UNALIGNED_DR (loop_vinfo);
   int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
@@ -3111,39 +3075,43 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree niters)
   basic_block new_bb;
   tree dr_stmt = DR_STMT (dr);
   stmt_vec_info stmt_info = vinfo_for_stmt (dr_stmt);
-  tree start_addr, byte_miss_align, elem_miss_align;
-  int vec_type_align = 
-    GET_MODE_ALIGNMENT (TYPE_MODE (STMT_VINFO_VECTYPE (stmt_info))) 
-                                                       / BITS_PER_UNIT;
-  tree tmp1, tmp2;
-  tree new_stmt_list = NULL_TREE;
-
-  start_addr = vect_create_addr_base_for_vector_ref (dr_stmt,
-                                                    &new_stmt_list, NULL_TREE);
+  tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+  int vectype_align = TYPE_ALIGN (vectype) / BITS_PER_UNIT;
+  tree elem_misalign;
+  tree byte_misalign;
+  tree new_stmts = NULL_TREE;
+  tree start_addr = 
+       vect_create_addr_base_for_vector_ref (dr_stmt, &new_stmts, NULL_TREE);
+  tree ptr_type = TREE_TYPE (start_addr);
+  tree size = TYPE_SIZE (ptr_type);
+  tree type = lang_hooks.types.type_for_size (TREE_INT_CST_LOW (size), 1);
+  tree vectype_size_minus_1 = build_int_cst (type, vectype_align - 1);
+  tree vf_minus_1 = build_int_cst (unsigned_type_node, vf - 1);
+  tree niters_type = TREE_TYPE (loop_niters);
+  tree elem_size_log = 
+       build_int_cst (unsigned_type_node, exact_log2 (vectype_align/vf));
+  tree vf_tree = build_int_cst (unsigned_type_node, vf);
 
   pe = loop_preheader_edge (loop); 
-  new_bb = bsi_insert_on_edge_immediate (pe, new_stmt_list); 
+  new_bb = bsi_insert_on_edge_immediate (pe, new_stmts); 
   if (new_bb)
     add_bb_to_loop (new_bb, EDGE_PRED (new_bb, 0)->src->loop_father);
 
-  byte_miss_align = 
-       build (BIT_AND_EXPR, integer_type_node, start_addr, 
-                 build (MINUS_EXPR, integer_type_node, 
-                        build_int_cst (unsigned_type_node,
-                                       vec_type_align), integer_one_node));
-  tmp1 = build_int_cst (unsigned_type_node, vec_type_align/vf);
-  elem_miss_align = build (FLOOR_DIV_EXPR, integer_type_node, 
-                          byte_miss_align, tmp1); 
+  /* Create:  byte_misalign = addr & (vectype_size - 1)  */
+  byte_misalign = build2 (BIT_AND_EXPR, type, start_addr, vectype_size_minus_1);
+
+  /* Create:  elem_misalign = byte_misalign / element_size  */
+  elem_misalign = 
+       build2 (RSHIFT_EXPR, unsigned_type_node, byte_misalign, elem_size_log);
   
-  tmp2 = 
-       build (BIT_AND_EXPR, integer_type_node,
-         build (MINUS_EXPR, integer_type_node, 
-               build_int_cst (unsigned_type_node, vf), elem_miss_align),
-         build (MINUS_EXPR, integer_type_node, 
-               build_int_cst (unsigned_type_node, vf), integer_one_node)); 
-
-  iters = build2 (MIN_EXPR, TREE_TYPE (tmp2), tmp2, niters);
-  var = create_tmp_var (TREE_TYPE (iters), "iters");
+  /* Create:  (niters_type) (VF - elem_misalign)&(VF - 1)  */
+  iters = build2 (MINUS_EXPR, unsigned_type_node, vf_tree, elem_misalign);
+  iters = build2 (BIT_AND_EXPR, unsigned_type_node, iters, vf_minus_1);
+  iters = fold_convert (niters_type, iters);
+
+  /* Create:  prolog_loop_niters = min (iters, loop_niters) */
+  iters = build2 (MIN_EXPR, niters_type, iters, loop_niters);
+  var = create_tmp_var (niters_type, "prolog_loop_niters");
   add_referenced_tmp_var (var);
   iters_name = force_gimple_operand (iters, &stmt, false, var);
 
@@ -3252,7 +3220,7 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo, struct loops *loops)
   /* Update number of times loop executes.  */
   n_iters = LOOP_VINFO_NITERS (loop_vinfo);
   LOOP_VINFO_NITERS (loop_vinfo) =
-    build (MINUS_EXPR, integer_type_node, n_iters, niters_of_prolog_loop);
+    build2 (MINUS_EXPR, TREE_TYPE (n_iters), n_iters, niters_of_prolog_loop);
 
   /* Update the init conditions of the access functions of all data refs.  */
   vect_update_inits_of_drs (loop_vinfo, niters_of_prolog_loop);
@@ -3304,6 +3272,9 @@ vect_transform_loop (loop_vec_info loop_vinfo,
       || (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
           && LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0))
     vect_do_peeling_for_loop_bound (loop_vinfo, &ratio, loops);
+  else
+    ratio = build_int_cst (TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo)),
+               LOOP_VINFO_INT_NITERS (loop_vinfo) / vectorization_factor);
 
   /* 1) Make sure the loop header has exactly two entries
      2) Make sure we have a preheader basic block.  */
@@ -3366,7 +3337,7 @@ vect_transform_loop (loop_vec_info loop_vinfo,
        }                       /* stmts in BB */
     }                          /* BBs in loop */
 
-  vect_transform_loop_bound (loop_vinfo, ratio);
+  slpeel_make_loop_iterate_ntimes (loop, ratio);
 
   if (vect_debug_details (loop))
     fprintf (dump_file,"Success! loop vectorized.");