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
This commit is contained in:
Alexandre Oliva 2011-02-03 06:01:40 +00:00 committed by Alexandre Oliva
parent c94854734b
commit 1551d44aba
4 changed files with 62 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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)