Patchwork [PR,tree-optimization/45122] don't make too-unsafe loop assumptions

login
register
mail settings
Submitter Alexandre Oliva
Date Feb. 2, 2011, 3:29 p.m.
Message ID <orhbcmv4ji.fsf@livre.localdomain>
Download mbox | patch
Permalink /patch/81464/
State New
Headers show

Comments

Alexandre Oliva - Feb. 2, 2011, 3:29 p.m.
Given -funsafe-loop-optimizations, we used to discard the assumptions
that had to hold in order for the estimated loop trip count to apply.
It turns out that this is less likely to be reasonable behavior if the
loop has more than one exit, because the exit with the smallest
estimated trip count whose base assumption indicated it wouldn't apply
would end up prevailing over another exit test for which a larger trip
count was estimated, as in the given testcase.

This patch stops us from discarding these assumptions (or rather, from
making too-unsafe assumptions :-) when the loop has more than one exit.
Regstrapped on x86_64-linux-gnu and i686-pc-linux-gnu.  Ok to install?
Richard Guenther - Feb. 2, 2011, 3:34 p.m.
On Wed, Feb 2, 2011 at 4:29 PM, Alexandre Oliva <aoliva@redhat.com> wrote:
> Given -funsafe-loop-optimizations, we used to discard the assumptions
> that had to hold in order for the estimated loop trip count to apply.
> It turns out that this is less likely to be reasonable behavior if the
> loop has more than one exit, because the exit with the smallest
> estimated trip count whose base assumption indicated it wouldn't apply
> would end up prevailing over another exit test for which a larger trip
> count was estimated, as in the given testcase.
>
> This patch stops us from discarding these assumptions (or rather, from
> making too-unsafe assumptions :-) when the loop has more than one exit.
> Regstrapped on x86_64-linux-gnu and i686-pc-linux-gnu.  Ok to install?

Ok.

Thanks,
Richard.

Patch

for  gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR tree-optimization/45122
	* tree-ssa-loop-niter.c (number_of_iterations_exit): Don't make
	unsafe assumptions when there's more than one loop exit.

for  gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR tree-optimization/45122
	* gcc.dg/tree-ssa/pr45122.c: New.

Index: gcc/tree-ssa-loop-niter.c
===================================================================
--- gcc/tree-ssa-loop-niter.c.orig	2011-02-02 02:37:44.402903056 -0200
+++ gcc/tree-ssa-loop-niter.c	2011-02-02 03:04:16.656372360 -0200
@@ -1890,7 +1890,7 @@  number_of_iterations_exit (struct loop *
   /* With -funsafe-loop-optimizations we assume that nothing bad can happen.
      But if we can prove that there is overflow or some other source of weird
      behavior, ignore the loop even with -funsafe-loop-optimizations.  */
-  if (integer_zerop (niter->assumptions))
+  if (integer_zerop (niter->assumptions) || !single_exit (loop))
     return false;
 
   if (flag_unsafe_loop_optimizations)
Index: gcc/testsuite/gcc.dg/tree-ssa/pr45122.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.dg/tree-ssa/pr45122.c	2011-02-02 03:31:58.678557820 -0200
@@ -0,0 +1,50 @@ 
+/* PR tree-optimization/27285 */
+/* PR tree-optimization/45122 */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -funsafe-loop-optimizations" } */
+
+extern void abort (void);
+
+struct S { unsigned char a, b, c, d[16]; };
+
+void __attribute__ ((noinline))
+foo (struct S *x, struct S *y)
+{
+  int a, b;
+  unsigned char c, *d, *e;
+
+  b = x->b;
+  d = x->d;
+  e = y->d;
+  a = 0;
+  while (b)
+    {
+      if (b >= 8)
+	{
+	  c = 0xff;
+	  b -= 8;
+	}
+      else
+	{
+	  c = 0xff << (8 - b);
+	  b = 0;
+	}
+
+      e[a] = d[a] & c;
+      a++;
+    }
+}
+
+int
+main (void)
+{
+  struct S x = { 0, 25, 0, { 0xaa, 0xbb, 0xcc, 0xdd }};
+  struct S y = { 0, 0, 0, { 0 }};
+
+  foo (&x, &y);
+  if (x.d[0] != y.d[0] || x.d[1] != y.d[1]
+      || x.d[2] != y.d[2] || (x.d[3] & 0x80) != y.d[3])
+    abort ();
+   return 0;
+}