This is a strlen opt patch that better optimizes attached testcase; there's just no need to call strlen again, as we're not changing the length of the string. Unfortunately this still handles only p[0], not for instance p[1], p[2], ... so we likely don't want to put this in now. But I'm posting it at least for archive reasons anyway. It works by not invalidating the length cache if we're not storing \0 into a string and the length of a string is > 0.
Bootstrapped/regtested on x86_64-linux. 2013-05-15 Marek Polacek <pola...@redhat.com> * tree-ssa-strlen.c (handle_char_store): Don't invalidate cached length when doing non-zero store. * gcc.dg/strlenopt-25.c: New test. --- gcc/tree-ssa-strlen.c.mp 2013-05-15 14:11:20.079707492 +0200 +++ gcc/tree-ssa-strlen.c 2013-05-15 17:21:23.772094679 +0200 @@ -1717,6 +1717,11 @@ handle_char_store (gimple_stmt_iterator si->endptr = ssaname; si->dont_invalidate = true; } + else if (si != NULL && si->length != NULL_TREE + && TREE_CODE (si->length) == INTEGER_CST + && integer_nonzerop (gimple_assign_rhs1 (stmt)) + && tree_int_cst_sgn (si->length) > 0) + si->dont_invalidate = true; } else if (idx == 0 && initializer_zerop (gimple_assign_rhs1 (stmt))) { --- gcc/testsuite/gcc.dg/strlenopt-25.c.mp 2013-05-15 17:15:18.702118637 +0200 +++ gcc/testsuite/gcc.dg/strlenopt-25.c 2013-05-15 18:26:27.881030317 +0200 @@ -0,0 +1,18 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fdump-tree-strlen" } */ + +#include "strlenopt.h" + +int +main () +{ + char p[] = "foobar"; + int len, len2; + len = strlen (p); + p[0] = 'O'; + len2 = strlen (p); + return len - len2; +} + +/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */ +/* { dg-final { cleanup-tree-dump "strlen" } } */ Marek