vect: Use main loop's thresholds and VF to narrow upper_bound of epilogue
authorAndre Vieira <andre.simoesdiasvieira@arm.com>
Thu, 3 Jun 2021 12:55:24 +0000 (13:55 +0100)
committerAndre Vieira <andre.simoesdiasvieira@arm.com>
Thu, 3 Jun 2021 12:55:24 +0000 (13:55 +0100)
This patch uses the knowledge of the conditions to enter an epilogue loop to
help come up with a potentially more restricive upper bound.

gcc/ChangeLog:

* tree-vect-loop.c (vect_transform_loop): Use main loop's various'
thresholds to narrow the upper bound on epilogue iterations.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/sve/part_vect_single_iter_epilog.c: New test.

gcc/testsuite/gcc.target/aarch64/sve/part_vect_single_iter_epilog.c [new file with mode: 0644]
gcc/tree-vect-loop.c

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/part_vect_single_iter_epilog.c b/gcc/testsuite/gcc.target/aarch64/sve/part_vect_single_iter_epilog.c
new file mode 100644 (file)
index 0000000..a03229e
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 --param vect-partial-vector-usage=1" } */
+
+void
+foo (short * __restrict__ a, short * __restrict__ b, short * __restrict__ c, int n)
+{
+  for (int i = 0; i < n; ++i)
+    c[i] = a[i] + b[i];
+}
+
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-9]+.h, wzr, [xw][0-9]+} 1 } } */
index ff7673d..ba36348 100644 (file)
@@ -9740,12 +9740,31 @@ vect_transform_loop (loop_vec_info loop_vinfo, gimple *loop_vectorized_call)
   /* In these calculations the "- 1" converts loop iteration counts
      back to latch counts.  */
   if (loop->any_upper_bound)
-    loop->nb_iterations_upper_bound
-      = (final_iter_may_be_partial
-        ? wi::udiv_ceil (loop->nb_iterations_upper_bound + bias_for_lowest,
-                         lowest_vf) - 1
-        : wi::udiv_floor (loop->nb_iterations_upper_bound + bias_for_lowest,
-                          lowest_vf) - 1);
+    {
+      loop_vec_info main_vinfo = LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo);
+      loop->nb_iterations_upper_bound
+       = (final_iter_may_be_partial
+          ? wi::udiv_ceil (loop->nb_iterations_upper_bound + bias_for_lowest,
+                           lowest_vf) - 1
+          : wi::udiv_floor (loop->nb_iterations_upper_bound + bias_for_lowest,
+                            lowest_vf) - 1);
+      if (main_vinfo)
+       {
+         unsigned int bound;
+         poly_uint64 main_iters
+           = upper_bound (LOOP_VINFO_VECT_FACTOR (main_vinfo),
+                          LOOP_VINFO_COST_MODEL_THRESHOLD (main_vinfo));
+         main_iters
+           = upper_bound (main_iters,
+                          LOOP_VINFO_VERSIONING_THRESHOLD (main_vinfo));
+         if (can_div_away_from_zero_p (main_iters,
+                                       LOOP_VINFO_VECT_FACTOR (loop_vinfo),
+                                       &bound))
+           loop->nb_iterations_upper_bound
+             = wi::umin ((widest_int) (bound - 1),
+                         loop->nb_iterations_upper_bound);
+      }
+  }
   if (loop->any_likely_upper_bound)
     loop->nb_iterations_likely_upper_bound
       = (final_iter_may_be_partial