]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
loop-split improvements, part 1
authorJan Hubicka <jh@suse.cz>
Fri, 28 Jul 2023 07:16:09 +0000 (09:16 +0200)
committerJan Hubicka <jh@suse.cz>
Fri, 28 Jul 2023 07:16:09 +0000 (09:16 +0200)
while looking on profile misupdate on hmmer I noticed that loop splitting pass is not
able to handle the loop it has as an example it should apply on:

   One transformation of loops like:

   for (i = 0; i < 100; i++)
     {
       if (i < 50)
         A;
       else
         B;
     }

   into:

   for (i = 0; i < 50; i++)
     {
       A;
     }
   for (; i < 100; i++)
     {
       B;
     }

The problem is that ivcanon turns the test into i != 100 and the pass
explicitly gives up on any loops ending with != test.  It needs to know
the directoin of the induction variable in order to derive right conditions,
but that can be done also from step.

It turns out that there are no testcases for basic loop splitting.  I will add
some with the profile update fix.

gcc/ChangeLog:

* tree-ssa-loop-split.cc (split_loop): Also support NE driven
loops when IV test is not overflowing.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/ifc-12.c: Disable loop splitting.
* gcc.target/i386/avx2-gather-6.c: Likewise.
* gcc.target/i386/avx2-vect-aggressive.c: Likewise.

gcc/testsuite/gcc.dg/tree-ssa/ifc-12.c
gcc/testsuite/gcc.target/i386/avx2-gather-6.c
gcc/testsuite/gcc.target/i386/avx2-vect-aggressive.c
gcc/tree-ssa-loop-split.cc

index 9468c070489bd29016eaeab5a895ad782bb33267..7f09c381d9f40ca17cb966bfe036be786990a267 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-Ofast -fdump-tree-ifcvt-stats-blocks-details" } */
+/* { dg-options "-Ofast -fdump-tree-ifcvt-stats-blocks-details -fno-split-loops" } */
 /* { dg-require-visibility "" } */
 
 struct st
index b9119581ae2c9c37b613de201ec4de4ac5db06d7..47a95dbe9891270a3c23046a45c4e5a1244dbe5c 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O3 -mavx2 -fno-common -fdump-tree-vect-details -mtune=skylake" } */
+/* { dg-options "-O3 -mavx2 -fno-common -fdump-tree-vect-details -mtune=skylake -fno-split-loops" } */
 
 #include "avx2-gather-5.c"
 
index 5719279185729b645db592a52825796896b2f050..fa336e70e84c52f420be44c3dcc0bb0252b47e43 100644 (file)
@@ -1,6 +1,6 @@
 /* { dg-do run } */
 /* { dg-require-effective-target avx2 } */
-/* { dg-options "-mavx2 -O3 -fopenmp-simd -fdump-tree-vect-details -fdisable-tree-thread1" } */
+/* { dg-options "-mavx2 -O3 -fopenmp-simd -fdump-tree-vect-details -fdisable-tree-thread1 -fno-split-loops" } */
 
 #include "avx2-check.h"
 #define N 64
index b41b5e614c2177be190fb8553d0daa6cab2a8e4b..f441f3fe1b519ee210568db3da9e3e4fcae0557d 100644 (file)
@@ -540,10 +540,17 @@ split_loop (class loop *loop1)
       || !empty_block_p (loop1->latch)
       || !easy_exit_values (loop1)
       || !number_of_iterations_exit (loop1, exit1, &niter, false, true)
-      || niter.cmp == ERROR_MARK
-      /* We can't yet handle loops controlled by a != predicate.  */
-      || niter.cmp == NE_EXPR)
+      || niter.cmp == ERROR_MARK)
     return false;
+  if (niter.cmp == NE_EXPR)
+    {
+      if (!niter.control.no_overflow)
+       return false;
+      if (tree_int_cst_sign_bit (niter.control.step) > 0)
+       niter.cmp = GT_EXPR;
+      else
+       niter.cmp = LT_EXPR;
+    }
 
   bbs = get_loop_body (loop1);