public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Patch GCC/01]Bring back warning message on loop whose counter might overflow
@ 2016-07-21 16:48 Bin Cheng
  2016-07-22 11:39 ` Richard Biener
  0 siblings, 1 reply; 3+ messages in thread
From: Bin Cheng @ 2016-07-21 16:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: nd

[-- Attachment #1: Type: text/plain, Size: 865 bytes --]

Hi,
Previous patch removed warning message on loops whose counter might overflow, while this patch adds it back.  Reason is it's always good to have a warning message indicating missed loop optimizations.  Also warning message itself is slightly changed.
There will be following patch which removes -funsafe-loop-optimizations.

Bootstrap and test on x86_64.  Is it OK?

Thanks,
bin

2016-07-20  Bin Cheng  <bin.cheng@arm.com>

	* tree-ssa-loop-niter.h (number_of_iterations_exit_assumptions): New
	Parameter.
	* tree-ssa-loop-niter.c (number_of_iterations_exit_assumptions): New
	Parameter.
	(number_of_iterations_exit): Warn missed loop optimization for
	possible infinite loops.

gcc/testsuite/ChangeLog
2016-07-20  Bin Cheng  <bin.cheng@arm.com>

	* gcc.dg/tree-ssa/pr19210-1.c: Refine test strings.
	* gcc.dg/tree-ssa/pr19210-2.c: Delete.

[-- Attachment #2: warn-loop-optimizations-20160720.txt --]
[-- Type: text/plain, Size: 5007 bytes --]

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr19210-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr19210-1.c
index 906132c..3c8ee06 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr19210-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr19210-1.c
@@ -6,10 +6,10 @@ void
 f (unsigned n)
 {
   unsigned k;
-  for(k = 0;k <= n;k++) /* { dg-warning "cannot optimize.*infinite loops" } */
+  for(k = 0;k <= n;k++) /* { dg-warning "missed loop optimization.*overflow" } */
     g();
 
-  for(k = 0;k <= n;k += 4) /* { dg-warning "cannot optimize.*overflow" } */
+  for(k = 0;k <= n;k += 4) /* { dg-warning "missed loop optimization.*overflow" } */
     g();
 
   /* We used to get warning for this loop.  However, since then # of iterations
@@ -21,9 +21,9 @@ f (unsigned n)
     g();
 
   /* So we need the following loop, instead.  */
-  for(k = 4;k <= n;k += 5) /* { dg-warning "cannot optimize.*overflow" } */
+  for(k = 4;k <= n;k += 5) /* { dg-warning "missed loop optimization.*overflow" } */
     g();
   
-  for(k = 15;k >= n;k--) /* { dg-warning "cannot optimize.*infinite" } */
+  for(k = 15;k >= n;k--) /* { dg-warning "missed loop optimization.*overflow" } */
     g();
 }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr19210-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr19210-2.c
deleted file mode 100644
index 9116e97..0000000
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr19210-2.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -funsafe-loop-optimizations -Wunsafe-loop-optimizations" } */
-extern void g(void);
-
-void
-f (unsigned n)
-{
-  unsigned k;
-  for(k = 0;k <= n;k++) /* { dg-warning "assuming.*not infinite" } */
-    g();
-
-  for(k = 5;k <= n;k += 4) /* { dg-warning "assuming.*not overflow" } */
-    g();
-
-  /* We used to get warning for this loop.  However, since then # of iterations
-     analysis improved, and we can now prove that this loop does not verflow.
-     This is because the only case when it would overflow is if n = ~0 (since
-     ~0 is divisible by 5), and this cannot be the case, since when we got
-     here, the previous loop exited, thus there exists k > n.  */
-  for(k = 5;k <= n;k += 5)
-    g();
-
-  for(k = 4;k <= n;k += 5) /* { dg-warning "assuming.*not overflow" } */
-    g();
-
-  for(k = 15;k >= n;k--) /* { dg-warning "assuming.*not infinite" } */
-    g();
-
-}
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index d96c03b..48947f0 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -2181,12 +2181,13 @@ loop_only_exit_p (const struct loop *loop, const_edge exit)
    in comments at struct tree_niter_desc declaration), false otherwise.
    When EVERY_ITERATION is true, only tests that are known to be executed
    every iteration are considered (i.e. only test that alone bounds the loop).
- */
+   If AT_STMT is not NULL, this function stores LOOP's condition statement in
+   it when returning true.  */
 
 bool
 number_of_iterations_exit_assumptions (struct loop *loop, edge exit,
 				       struct tree_niter_desc *niter,
-				       bool every_iteration)
+				       gcond **at_stmt, bool every_iteration)
 {
   gimple *last;
   gcond *stmt;
@@ -2303,6 +2304,9 @@ number_of_iterations_exit_assumptions (struct loop *loop, edge exit,
   if (TREE_CODE (niter->niter) == INTEGER_CST)
     niter->max = wi::to_widest (niter->niter);
 
+  if (at_stmt)
+    *at_stmt = stmt;
+
   return (!integer_zerop (niter->assumptions));
 }
 
@@ -2312,13 +2316,27 @@ number_of_iterations_exit_assumptions (struct loop *loop, edge exit,
 bool
 number_of_iterations_exit (struct loop *loop, edge exit,
 			   struct tree_niter_desc *niter,
-			   bool, bool every_iteration)
+			   bool warn, bool every_iteration)
 {
+  gcond *stmt;
   if (!number_of_iterations_exit_assumptions (loop, exit, niter,
-					      every_iteration))
+					      &stmt, every_iteration))
     return false;
 
-  return (integer_nonzerop (niter->assumptions));
+  if (integer_nonzerop (niter->assumptions))
+    return true;
+
+  if (warn)
+    {
+      const char *wording;
+      location_t loc = gimple_location (stmt);
+
+      wording = N_("missed loop optimization, the loop counter may overflow");
+      warning_at ((LOCATION_LINE (loc) > 0) ? loc : input_location,
+		  OPT_Wunsafe_loop_optimizations, "%s", gettext (wording));
+    }
+
+  return false;
 }
 
 /* Try to determine the number of iterations of LOOP.  If we succeed,
diff --git a/gcc/tree-ssa-loop-niter.h b/gcc/tree-ssa-loop-niter.h
index 1aea580..e46b829 100644
--- a/gcc/tree-ssa-loop-niter.h
+++ b/gcc/tree-ssa-loop-niter.h
@@ -29,7 +29,7 @@ extern bool number_of_iterations_exit (struct loop *, edge,
 				       bool every_iteration = true);
 extern bool number_of_iterations_exit_assumptions (struct loop *, edge,
 						   struct tree_niter_desc *,
-						   bool = true);
+						   gcond **, bool = true);
 extern tree find_loop_niter (struct loop *, edge *);
 extern bool finite_loop_p (struct loop *);
 extern tree loop_niter_by_eval (struct loop *, edge);

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Patch GCC/01]Bring back warning message on loop whose counter might overflow
  2016-07-21 16:48 [Patch GCC/01]Bring back warning message on loop whose counter might overflow Bin Cheng
@ 2016-07-22 11:39 ` Richard Biener
  2016-07-22 12:15   ` Bin.Cheng
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Biener @ 2016-07-22 11:39 UTC (permalink / raw)
  To: Bin Cheng; +Cc: gcc-patches, nd

On Thu, Jul 21, 2016 at 6:48 PM, Bin Cheng <Bin.Cheng@arm.com> wrote:
> Hi,
> Previous patch removed warning message on loops whose counter might overflow, while this patch adds it back.  Reason is it's always good to have a warning message indicating missed loop optimizations.  Also warning message itself is slightly changed.
> There will be following patch which removes -funsafe-loop-optimizations.
>
> Bootstrap and test on x86_64.  Is it OK?

Please do not use 'input_location'.  You never should check
LOCATION_LINE either but
just for loc != UNKNOWN_LOCATION.  Note that simply passing
gimple_location should
work and fall back to sth sensible for UNKNOWN_LOCATION.

Ok with that change,
Richard.

> Thanks,
> bin
>
> 2016-07-20  Bin Cheng  <bin.cheng@arm.com>
>
>         * tree-ssa-loop-niter.h (number_of_iterations_exit_assumptions): New
>         Parameter.
>         * tree-ssa-loop-niter.c (number_of_iterations_exit_assumptions): New
>         Parameter.
>         (number_of_iterations_exit): Warn missed loop optimization for
>         possible infinite loops.
>
> gcc/testsuite/ChangeLog
> 2016-07-20  Bin Cheng  <bin.cheng@arm.com>
>
>         * gcc.dg/tree-ssa/pr19210-1.c: Refine test strings.
>         * gcc.dg/tree-ssa/pr19210-2.c: Delete.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Patch GCC/01]Bring back warning message on loop whose counter might overflow
  2016-07-22 11:39 ` Richard Biener
@ 2016-07-22 12:15   ` Bin.Cheng
  0 siblings, 0 replies; 3+ messages in thread
From: Bin.Cheng @ 2016-07-22 12:15 UTC (permalink / raw)
  To: Richard Biener; +Cc: Bin Cheng, gcc-patches, nd

[-- Attachment #1: Type: text/plain, Size: 884 bytes --]

On Fri, Jul 22, 2016 at 12:39 PM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Thu, Jul 21, 2016 at 6:48 PM, Bin Cheng <Bin.Cheng@arm.com> wrote:
>> Hi,
>> Previous patch removed warning message on loops whose counter might overflow, while this patch adds it back.  Reason is it's always good to have a warning message indicating missed loop optimizations.  Also warning message itself is slightly changed.
>> There will be following patch which removes -funsafe-loop-optimizations.
>>
>> Bootstrap and test on x86_64.  Is it OK?
>
> Please do not use 'input_location'.  You never should check
> LOCATION_LINE either but
> just for loc != UNKNOWN_LOCATION.  Note that simply passing
> gimple_location should
> work and fall back to sth sensible for UNKNOWN_LOCATION.
>
> Ok with that change,
Thanks for reviewing, attachment is the updated patch.

Thanks,
bin
> Richard.
>

[-- Attachment #2: warn-loop-optimizations-20160721.txt --]
[-- Type: text/plain, Size: 4938 bytes --]

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr19210-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr19210-1.c
index 906132c..3c8ee06 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr19210-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr19210-1.c
@@ -6,10 +6,10 @@ void
 f (unsigned n)
 {
   unsigned k;
-  for(k = 0;k <= n;k++) /* { dg-warning "cannot optimize.*infinite loops" } */
+  for(k = 0;k <= n;k++) /* { dg-warning "missed loop optimization.*overflow" } */
     g();
 
-  for(k = 0;k <= n;k += 4) /* { dg-warning "cannot optimize.*overflow" } */
+  for(k = 0;k <= n;k += 4) /* { dg-warning "missed loop optimization.*overflow" } */
     g();
 
   /* We used to get warning for this loop.  However, since then # of iterations
@@ -21,9 +21,9 @@ f (unsigned n)
     g();
 
   /* So we need the following loop, instead.  */
-  for(k = 4;k <= n;k += 5) /* { dg-warning "cannot optimize.*overflow" } */
+  for(k = 4;k <= n;k += 5) /* { dg-warning "missed loop optimization.*overflow" } */
     g();
   
-  for(k = 15;k >= n;k--) /* { dg-warning "cannot optimize.*infinite" } */
+  for(k = 15;k >= n;k--) /* { dg-warning "missed loop optimization.*overflow" } */
     g();
 }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr19210-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr19210-2.c
deleted file mode 100644
index 9116e97..0000000
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr19210-2.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -funsafe-loop-optimizations -Wunsafe-loop-optimizations" } */
-extern void g(void);
-
-void
-f (unsigned n)
-{
-  unsigned k;
-  for(k = 0;k <= n;k++) /* { dg-warning "assuming.*not infinite" } */
-    g();
-
-  for(k = 5;k <= n;k += 4) /* { dg-warning "assuming.*not overflow" } */
-    g();
-
-  /* We used to get warning for this loop.  However, since then # of iterations
-     analysis improved, and we can now prove that this loop does not verflow.
-     This is because the only case when it would overflow is if n = ~0 (since
-     ~0 is divisible by 5), and this cannot be the case, since when we got
-     here, the previous loop exited, thus there exists k > n.  */
-  for(k = 5;k <= n;k += 5)
-    g();
-
-  for(k = 4;k <= n;k += 5) /* { dg-warning "assuming.*not overflow" } */
-    g();
-
-  for(k = 15;k >= n;k--) /* { dg-warning "assuming.*not infinite" } */
-    g();
-
-}
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index d96c03b..3697fbf 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -2181,12 +2181,13 @@ loop_only_exit_p (const struct loop *loop, const_edge exit)
    in comments at struct tree_niter_desc declaration), false otherwise.
    When EVERY_ITERATION is true, only tests that are known to be executed
    every iteration are considered (i.e. only test that alone bounds the loop).
- */
+   If AT_STMT is not NULL, this function stores LOOP's condition statement in
+   it when returning true.  */
 
 bool
 number_of_iterations_exit_assumptions (struct loop *loop, edge exit,
 				       struct tree_niter_desc *niter,
-				       bool every_iteration)
+				       gcond **at_stmt, bool every_iteration)
 {
   gimple *last;
   gcond *stmt;
@@ -2303,6 +2304,9 @@ number_of_iterations_exit_assumptions (struct loop *loop, edge exit,
   if (TREE_CODE (niter->niter) == INTEGER_CST)
     niter->max = wi::to_widest (niter->niter);
 
+  if (at_stmt)
+    *at_stmt = stmt;
+
   return (!integer_zerop (niter->assumptions));
 }
 
@@ -2312,13 +2316,26 @@ number_of_iterations_exit_assumptions (struct loop *loop, edge exit,
 bool
 number_of_iterations_exit (struct loop *loop, edge exit,
 			   struct tree_niter_desc *niter,
-			   bool, bool every_iteration)
+			   bool warn, bool every_iteration)
 {
+  gcond *stmt;
   if (!number_of_iterations_exit_assumptions (loop, exit, niter,
-					      every_iteration))
+					      &stmt, every_iteration))
     return false;
 
-  return (integer_nonzerop (niter->assumptions));
+  if (integer_nonzerop (niter->assumptions))
+    return true;
+
+  if (warn)
+    {
+      const char *wording;
+
+      wording = N_("missed loop optimization, the loop counter may overflow");
+      warning_at (gimple_location_safe (stmt),
+		  OPT_Wunsafe_loop_optimizations, "%s", gettext (wording));
+    }
+
+  return false;
 }
 
 /* Try to determine the number of iterations of LOOP.  If we succeed,
diff --git a/gcc/tree-ssa-loop-niter.h b/gcc/tree-ssa-loop-niter.h
index 1aea580..e46b829 100644
--- a/gcc/tree-ssa-loop-niter.h
+++ b/gcc/tree-ssa-loop-niter.h
@@ -29,7 +29,7 @@ extern bool number_of_iterations_exit (struct loop *, edge,
 				       bool every_iteration = true);
 extern bool number_of_iterations_exit_assumptions (struct loop *, edge,
 						   struct tree_niter_desc *,
-						   bool = true);
+						   gcond **, bool = true);
 extern tree find_loop_niter (struct loop *, edge *);
 extern bool finite_loop_p (struct loop *);
 extern tree loop_niter_by_eval (struct loop *, edge);

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-07-22 12:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-21 16:48 [Patch GCC/01]Bring back warning message on loop whose counter might overflow Bin Cheng
2016-07-22 11:39 ` Richard Biener
2016-07-22 12:15   ` Bin.Cheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).