Hi! Apparently I forgot to add code for complete invalidation of everything, if more than 100 stmts with vdefs are seen in between immediate dominator and current basic block. That cutoff is there so that we don't spend too much time on invalidation, but without this patch it actually ignored all the other vdef stmts in between those two bbs rather than just starting with no known string lengths at the start of the bb.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.8? 2013-08-30 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/58277 * tree-ssa-strlen.c (strlen_enter_block): If do_invalidate gave up after seeing too many stmts with vdef in between dombb and current bb, invalidate everything. * gcc.c-torture/execute/pr58277-1.c: New test. * gcc.c-torture/execute/pr58277-2.c: New test. --- gcc/tree-ssa-strlen.c.jj 2013-08-13 12:20:27.000000000 +0200 +++ gcc/tree-ssa-strlen.c 2013-08-30 11:02:39.717691590 +0200 @@ -1952,6 +1952,28 @@ strlen_enter_block (struct dom_walk_data int count_vdef = 100; do_invalidate (dombb, phi, visited, &count_vdef); BITMAP_FREE (visited); + if (count_vdef == 0) + { + /* If there were too many vdefs in between immediate + dominator and current bb, invalidate everything. + If stridx_to_strinfo has been unshared, we need + to free it, otherwise just set it to NULL. */ + if (!strinfo_shared ()) + { + unsigned int i; + strinfo si; + + for (i = 1; + vec_safe_iterate (stridx_to_strinfo, i, &si); + ++i) + { + free_strinfo (si); + (*stridx_to_strinfo)[i] = NULL; + } + } + else + stridx_to_strinfo = NULL; + } break; } } --- gcc/testsuite/gcc.c-torture/execute/pr58277-1.c.jj 2013-08-30 11:10:36.590005465 +0200 +++ gcc/testsuite/gcc.c-torture/execute/pr58277-1.c 2013-08-30 11:10:05.000000000 +0200 @@ -0,0 +1,102 @@ +/* PR tree-optimization/58277 */ + +extern void abort (void); +static int a[2]; +int b, c, d, *e, f, g, h, **i = &e, k, l = 1, n, o, p; +static int **volatile j = &e; +const int m; +char u; + +int +bar () +{ + u = 0; + return m; +} + +__attribute__((noinline, noclone)) void +baz () +{ + asm (""); +} + +static int +foo () +{ + int t1; + g = bar (); + if (l) + ; + else + for (;; h++) + { + *i = 0; + o = *e = 0; + if (p) + { + f = 0; + return 0; + } + for (;; k++) + { + int *t2 = 0; + int *const *t3[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, &t2, 0, 0, &t2, &t2, &t2, + &t2, &t2, 0, 0, 0, 0, 0, 0, 0, &t2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, &t2, 0, 0, 0, 0, 0, 0, 0, &t2, &t2, + &t2, &t2, &t2, 0, 0, 0, 0, 0, 0, 0, &t2, 0, 0, 0, + &t2, 0, 0, 0, &t2, 0, &t2, 0, 0, &t2, 0, 0, 0, 0, + 0, &t2, 0, 0, 0, 0, &t2, &t2, 0, 0, 0, 0, &t2, 0, + 0, 0, 0, 0, 0, 0, &t2, 0, 0, 0, 0, 0, &t2, 0, 0, 0, + &t2, &t2 + }; + int *const **t4[] = {&t3[0]}; + **i = 0; + if (**j) + break; + u = 0; + } + *i = *j; + t1 = 0; + for (; t1 < 5; t1++) + *i = *j; + } + *j = 0; + return 1; +} + +int +main () +{ + int t5; + a[0] = 1; + { + int *t6[6] = {&d, &d}; + for (n = 1; n; n--) + if (foo()) + { + int *t7[] = {0}; + d = 0; + for (; u < 1; u++) + *i = *j; + *i = 0; + *i = 0; + int t8[5] = {0}; + *i = &t8[0]; + int *const *t9 = &t6[0]; + int *const **t10 = &t9; + *t10 = &t7[0]; + } + } + u = 0; + for (; b; b++) + for (t5 = 0; t5 < 10; t5++) + c = a[a[a[a[a[a[a[a[c]]]]]]]]; + + baz (); + + if (!a[a[a[a[a[a[a[a[a[a[a[a[a[a[a[u]]]]]]]]]]]]]]]) + abort (); + + return 0; +} --- gcc/testsuite/gcc.c-torture/execute/pr58277-2.c.jj 2013-08-30 11:10:39.613988421 +0200 +++ gcc/testsuite/gcc.c-torture/execute/pr58277-2.c 2013-08-30 11:06:17.000000000 +0200 @@ -0,0 +1,98 @@ +/* PR tree-optimization/58277 */ + +extern void abort (void); +static int a[1], b, c, e, i, j, k, m, q[] = { 1, 1 }, t; +int volatile d; +int **r; +static int ***volatile s = &r; +int f, g, o, x; +static int *volatile h = &f, *p; +char n; + +static void +fn1 () +{ + b = a[a[a[a[a[a[a[a[b]]]]]]]]; + b = a[a[a[a[a[a[a[a[b]]]]]]]]; + b = a[a[b]]; + b = a[a[a[a[a[a[a[a[b]]]]]]]]; + b = a[a[a[a[a[a[a[a[b]]]]]]]]; +} + +static int +fn2 () +{ + n = 0; + for (; g; t++) + { + for (;; m++) + { + d; + int *u; + int **v[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, &u, 0, 0, 0, 0, &u, &u, &u, &u, &u, &u, &u, 0, + &u, 0, &u, &u, &u, 0, &u, &u, 0, &u, &u, &u, &u, 0, &u, &u, &u, + &u, &u, 0, &u, &u, 0, &u, 0, &u, &u, 0, &u, &u, &u, &u, &u, 0, + &u, 0, 0, 0, &u, &u, &u, 0, 0, &u, &u, &u, 0, &u, 0, &u, &u + }; + int ***w[] = { &v[0] }; + if (*p) + break; + return 0; + } + *h = 0; + } + return 1; +} + +static void +fn3 () +{ + int *y[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + for (; i; i++) + x = 0; + if (fn2 ()) + { + int *z[6] = { }; + for (; n < 1; n++) + *h = 0; + int t1[7]; + for (; c; c++) + o = t1[0]; + for (; e; e--) + { + int **t2 = &y[0]; + int ***t3 = &t2; + *t3 = &z[0]; + } + } + *s = 0; + for (n = 0;; n = 0) + { + int t4 = 0; + if (q[n]) + break; + *r = &t4; + } +} + +int +main () +{ + for (; j; j--) + a[0] = 0; + fn3 (); + for (; k; k++) + fn1 (); + fn1 (); + + if (n) + abort (); + + return 0; +} Jakub