]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/113371 - avoid prologue peeling for peeled early exits
authorRichard Biener <rguenther@suse.de>
Tue, 16 Jan 2024 12:09:27 +0000 (13:09 +0100)
committerRichard Biener <rguenther@suse.de>
Wed, 17 Jan 2024 08:22:32 +0000 (09:22 +0100)
The following avoids prologue peeling when doing early exit
vectorization with the IV exit before the early exit.  That's because
we it invalidates the invariant that the effective latch of the loop
is empty causing wrong continuation to the main loop.  In particular
this is prone to break virtual SSA form.

PR tree-optimization/113371
* tree-vect-data-refs.cc (vect_enhance_data_refs_alignment):
Do not peel when LOOP_VINFO_EARLY_BREAKS_VECT_PEELED.
* tree-vect-loop-manip.cc (vect_do_peeling): Assert we do
not perform prologue peeling when LOOP_VINFO_EARLY_BREAKS_VECT_PEELED.

* gcc.dg/vect/pr113371.c: New testcase.

gcc/testsuite/gcc.dg/vect/pr113371.c [new file with mode: 0644]
gcc/tree-vect-data-refs.cc
gcc/tree-vect-loop-manip.cc

diff --git a/gcc/testsuite/gcc.dg/vect/pr113371.c b/gcc/testsuite/gcc.dg/vect/pr113371.c
new file mode 100644 (file)
index 0000000..46c4deb
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O" } */
+/* { dg-additional-options "-march=silvermont" { target { x86_64-*-* i?86-*-* } } } */
+
+long *BN_uadd_ap;
+
+void
+BN_uadd (int dif, long t1)
+{
+  long *rp;
+  while (dif)
+    {
+      dif--;
+      t1 = *BN_uadd_ap;
+      *rp++ = t1;
+      if (t1)
+        break;
+    }
+}
index 5e86da394680956ee5140f01be72a203cba9ebee..0495842b35050d024018c08a150d04a6dce0a86d 100644 (file)
@@ -2354,8 +2354,9 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
   /* Check if we can possibly peel the loop.  */
   if (!vect_can_advance_ivs_p (loop_vinfo)
       || !slpeel_can_duplicate_loop_p (loop, LOOP_VINFO_IV_EXIT (loop_vinfo),
-                                      LOOP_VINFO_IV_EXIT (loop_vinfo))
-      || loop->inner)
+                                      loop_preheader_edge (loop))
+      || loop->inner
+      || LOOP_VINFO_EARLY_BREAKS_VECT_PEELED (loop_vinfo))
     do_peeling = false;
 
   struct _vect_peel_extended_info peel_for_known_alignment;
index c7e73f65155930fae2713d410f179616b3e12388..8aa9224e1a98b718b899a5d408e94a457dd42acf 100644 (file)
@@ -3262,7 +3262,8 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
     {
       e = loop_preheader_edge (loop);
       edge exit_e = LOOP_VINFO_IV_EXIT (loop_vinfo);
-      gcc_checking_assert (slpeel_can_duplicate_loop_p (loop, exit_e, e));
+      gcc_checking_assert (slpeel_can_duplicate_loop_p (loop, exit_e, e)
+                          && !LOOP_VINFO_EARLY_BREAKS_VECT_PEELED (loop_vinfo));
 
       /* Peel prolog and put it on preheader edge of loop.  */
       edge scalar_e = LOOP_VINFO_SCALAR_IV_EXIT (loop_vinfo);