From 1551d44aba2deeb55393396502ca091e41bcfee3 Mon Sep 17 00:00:00 2001
From: Alexandre Oliva <aoliva@redhat.com>
Date: Thu, 3 Feb 2011 06:01:40 +0000
Subject: [PATCH] re PR tree-optimization/45122 (-funsafe-loop-optimizations
 causes FAIL: gcc.c-torture/execute/pr27285.c execution)

gcc/ChangeLog:
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.
gcc/testsuite/ChangeLog:
PR tree-optimization/45122
* gcc.dg/tree-ssa/pr45122.c: New.

From-SVN: r169781
---
 gcc/ChangeLog                           |  6 +++
 gcc/testsuite/ChangeLog                 |  5 +++
 gcc/testsuite/gcc.dg/tree-ssa/pr45122.c | 50 +++++++++++++++++++++++++
 gcc/tree-ssa-loop-niter.c               |  2 +-
 4 files changed, 62 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr45122.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1f16f47ea8da..de9d846b7d35 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2011-02-03  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.
+
 2011-02-02  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
 	PR target/47272
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index de8cec788883..69da9d62bd8e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-02-03  Alexandre Oliva  <aoliva@redhat.com>
+
+	PR tree-optimization/45122
+	* gcc.dg/tree-ssa/pr45122.c: New.
+
 2011-02-02  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
 	PR target/47272
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr45122.c b/gcc/testsuite/gcc.dg/tree-ssa/pr45122.c
new file mode 100644
index 000000000000..e979b766fea7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr45122.c
@@ -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;
+}
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index ee85f6fe0063..c14e13c7248b 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -1890,7 +1890,7 @@ number_of_iterations_exit (struct loop *loop, edge exit,
   /* 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)
-- 
GitLab