Check the VF is small enough for an epilogue loop
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 6 Nov 2019 12:29:47 +0000 (12:29 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 6 Nov 2019 12:29:47 +0000 (12:29 +0000)
The number of iterations of an epilogue loop is always smaller than the
VF of the main loop.  vect_analyze_loop_costing was taking this into
account when deciding whether the loop is cheap enough to vectorise,
but that has no effect with the unlimited cost model.  We need to use
a separate check for correctness as well.

This can happen if the sizes returned by autovectorize_vector_sizes
happen to be out of order, e.g. because the target prefers smaller
vectors.  It can also happen with later patches if two vectorisation
attempts happen to end up with the same VF.

2019-11-06  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
* tree-vect-loop.c (vect_analyze_loop_2): When vectorizing an
epilogue loop, make sure that the VF is small enough or that
the epilogue loop can be fully-masked.

From-SVN: r277880

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

index a8a8968c9bc3c81df8f293ed63cf2c169113757e..d04b6bea18bcf44817c5dff2386a7028eb8c23c9 100644 (file)
@@ -1,3 +1,9 @@
+2019-11-06  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * tree-vect-loop.c (vect_analyze_loop_2): When vectorizing an
+       epilogue loop, make sure that the VF is small enough or that
+       the epilogue loop can be fully-masked.
+
 2019-11-06  Richard Sandiford  <richard.sandiford@arm.com>
 
        * tree-vect-loop.c (vect_analyze_loop): Break out of the main
index f8049047a8e3818cc1ff52e6e1ca6adfc3d2af91..ec0bd2c3875a5d9ec5e7522b01c325ac0ab3c369 100644 (file)
@@ -2143,6 +2143,16 @@ start_over:
                                       " support peeling for gaps.\n");
     }
 
+  /* If we're vectorizing an epilogue loop, we either need a fully-masked
+     loop or a loop that has a lower VF than the main loop.  */
+  if (LOOP_VINFO_EPILOGUE_P (loop_vinfo)
+      && !LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)
+      && maybe_ge (LOOP_VINFO_VECT_FACTOR (loop_vinfo),
+                  LOOP_VINFO_VECT_FACTOR (orig_loop_vinfo)))
+    return opt_result::failure_at (vect_location,
+                                  "Vectorization factor too high for"
+                                  " epilogue loop.\n");
+
   /* Check the costings of the loop make vectorizing worthwhile.  */
   res = vect_analyze_loop_costing (loop_vinfo);
   if (res < 0)