summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2011-02-03 06:01:40 +0000
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2011-02-03 06:01:40 +0000
commit4f2bfa26e4630b905c43dd852395b2d5047d388c (patch)
tree24e9cf0f5046d167fed3c35adba388143c7ffc46
parenta501acdaaacf5f3b1fa97242ff4f38cc1d87553d (diff)
downloadgcc-4f2bfa26e4630b905c43dd852395b2d5047d388c.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@169781 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr45122.c50
-rw-r--r--gcc/tree-ssa-loop-niter.c2
4 files changed, 62 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1f16f47ea8d..de9d846b7d3 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 de8cec78888..69da9d62bd8 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 00000000000..e979b766fea
--- /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 ee85f6fe006..c14e13c7248 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)