tree-vect-loop.c (loop_niters_no_overflow): New func.
authorBin Cheng <bin.cheng@arm.com>
Thu, 13 Oct 2016 11:09:23 +0000 (11:09 +0000)
committerBin Cheng <amker@gcc.gnu.org>
Thu, 13 Oct 2016 11:09:23 +0000 (11:09 +0000)
* tree-vect-loop.c (loop_niters_no_overflow): New func.
(vect_transform_loop): Call loop_niters_no_overflow.  Pass the
no-overflow information to vect_do_peeling_for_loop_bound and
vect_gen_vector_loop_niters.

From-SVN: r241102

gcc/ChangeLog
gcc/tree-vect-loop.c

index 76ff0930d49d521d86e9d0b46d8942c996579112..8bfe53244f9d365396e28ddb25ffbf3cfe46d27e 100644 (file)
@@ -1,3 +1,10 @@
+2016-10-13  Bin Cheng  <bin.cheng@arm.com>
+
+       * tree-vect-loop.c (loop_niters_no_overflow): New func.
+       (vect_transform_loop): Call loop_niters_no_overflow.  Pass the
+       no-overflow information to vect_do_peeling_for_loop_bound and
+       vect_gen_vector_loop_niters.
+
 2016-10-13  Bin Cheng  <bin.cheng@arm.com>
 
        * tree-predcom.c (tree_predictive_commoning_loop): Skip loop that only
index 0470445de81d284216d07bdb2927a69266db7f50..9cca9b717a6990042190f9a49e97cfa8cd94af44 100644 (file)
@@ -6620,6 +6620,39 @@ vect_loop_kill_debug_uses (struct loop *loop, gimple *stmt)
     }
 }
 
+/* Given loop represented by LOOP_VINFO, return true if computation of
+   LOOP_VINFO_NITERS (= LOOP_VINFO_NITERSM1 + 1) doesn't overflow, false
+   otherwise.  */
+
+static bool
+loop_niters_no_overflow (loop_vec_info loop_vinfo)
+{
+  /* Constant case.  */
+  if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
+    {
+      tree cst_niters = LOOP_VINFO_NITERS (loop_vinfo);
+      tree cst_nitersm1 = LOOP_VINFO_NITERSM1 (loop_vinfo);
+
+      gcc_assert (TREE_CODE (cst_niters) == INTEGER_CST);
+      gcc_assert (TREE_CODE (cst_nitersm1) == INTEGER_CST);
+      if (wi::to_widest (cst_nitersm1) < wi::to_widest (cst_niters))
+       return true;
+    }
+
+  widest_int max;
+  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+  /* Check the upper bound of loop niters.  */
+  if (get_max_loop_iterations (loop, &max))
+    {
+      tree type = TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo));
+      signop sgn = TYPE_SIGN (type);
+      widest_int type_max = widest_int::from (wi::max_value (type), sgn);
+      if (max < type_max)
+       return true;
+    }
+  return false;
+}
+
 /* Function vect_transform_loop.
 
    The analysis phase has determined that the loop is vectorizable.
@@ -6707,8 +6740,9 @@ vect_transform_loop (loop_vec_info loop_vinfo)
   tree niters = vect_build_loop_niters (loop_vinfo);
   LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo) = niters;
   tree nitersm1 = unshare_expr (LOOP_VINFO_NITERSM1 (loop_vinfo));
+  bool niters_no_overflow = loop_niters_no_overflow (loop_vinfo);
   vect_do_peeling (loop_vinfo, niters, nitersm1, &niters_vector, th,
-                  check_profitability, false);
+                  check_profitability, niters_no_overflow);
   if (niters_vector == NULL_TREE)
     {
       if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
@@ -6717,7 +6751,7 @@ vect_transform_loop (loop_vec_info loop_vinfo)
                           LOOP_VINFO_INT_NITERS (loop_vinfo) / vf);
       else
        vect_gen_vector_loop_niters (loop_vinfo, niters, &niters_vector,
-                                    false);
+                                    niters_no_overflow);
     }
 
   /* 1) Make sure the loop header has exactly two entries