Call finite_loop_p in RTL to get better finiteness information.
authorKewen Lin <linkw@gcc.gnu.org>
Thu, 27 Jun 2019 05:24:00 +0000 (05:24 +0000)
committerKewen Lin <linkw@gcc.gnu.org>
Thu, 27 Jun 2019 05:24:00 +0000 (05:24 +0000)
gcc/ChangeLog

2019-06-27  Kewen Lin  <linkw@gcc.gnu.org>

    PR target/62147
    * gcc/loop-iv.c (find_simple_exit): Call finite_loop_p to update finiteness.

gcc/testsuite/ChangeLog

2019-06-27  Kewen Lin  <linkw@gcc.gnu.org>

    PR target/62147
    * gcc.target/powerpc/pr62147.c: New test.

From-SVN: r272731

gcc/ChangeLog
gcc/loop-iv.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr62147.c [new file with mode: 0644]

index 01fb97cedb23568af88db1774c2aedefd33b3c08..4a96eb5a1577c5cfa0dcf783504e00cbfa7966c7 100644 (file)
@@ -1,3 +1,9 @@
+2019-06-27  Kewen Lin  <linkw@gcc.gnu.org>
+
+       PR target/62147
+       * gcc/loop-iv.c (find_simple_exit): Call finite_loop_p to update
+       finiteness.
+
 2019-06-26  Jeff Law  <law@redhat.com>
 
        PR tree-optimization/90883
index 82b4bdb15232a4eb16c257f36c18335cae628b68..36f9856f5f688407828ea055ab2813d940488bc7 100644 (file)
@@ -61,6 +61,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "intl.h"
 #include "dumpfile.h"
 #include "rtl-iter.h"
+#include "tree-ssa-loop-niter.h"
 
 /* Possible return values of iv_get_reaching_def.  */
 
@@ -2997,6 +2998,19 @@ find_simple_exit (struct loop *loop, struct niter_desc *desc)
        fprintf (dump_file, "Loop %d is not simple.\n", loop->num);
     }
 
+  /* Fix up the finiteness if possible.  We can only do it for single exit,
+     since the loop is finite, but it's possible that we predicate one loop
+     exit to be finite which can not be determined as finite in middle-end as
+     well.  It results in incorrect predicate information on the exit condition
+     expression.  For example, if says [(int) _1 + -8, + , -8] != 0 finite,
+     it means _1 can exactly divide -8.  */
+  if (single_exit (loop) && finite_loop_p (loop))
+    {
+      desc->infinite = NULL_RTX;
+      if (dump_file)
+       fprintf (dump_file, "  infinite updated to finite.\n");
+    }
+
   free (body);
 }
 
index eb5340122a4110dc8ae92301c699a6b2aaa7f639..90dcc34a7858adb3976cbeb4300a697c5bfb4b89 100644 (file)
@@ -1,6 +1,11 @@
+2019-06-27  Kewen Lin  <linkw@gcc.gnu.org>
+
+       PR target/62147
+       * gcc.target/powerpc/pr62147.c: New test.
+
 2019-06-26  Jeff Law  <law@redhat.com>
 
-        PR tree-optimization/90883
+       PR tree-optimization/90883
        * g++.dg/tree-ssa/pr90883.C: New test.
        * gcc.dg/tree-ssa/ssa-dse-36.c: New test.
 
diff --git a/gcc/testsuite/gcc.target/powerpc/pr62147.c b/gcc/testsuite/gcc.target/powerpc/pr62147.c
new file mode 100644 (file)
index 0000000..635c737
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-O2 -fno-tree-loop-distribute-patterns" } */
+
+/* Note that it's required to disable loop-distribute-patterns, otherwise the
+   loop will be optimized to memset.  */
+
+/* Expect loop_iv can know the loop is finite so the doloop_optimize
+   can perform the doloop transformation.  */
+
+typedef struct {
+  int l;
+  int b[258];
+} S;
+
+void clear (S* s )
+{
+  int i;
+  int len = s->l + 1;
+
+  for (i = 0; i <= len; i++)
+    s->b[i] = 0;
+}
+
+/* { dg-final { scan-assembler {\mbdnz\M} } } */