On 04/06/15 15:23, Ondřej Bílka wrote: > On Thu, Jun 04, 2015 at 02:59:20PM +0200, Jakub Jelinek wrote: >> On Thu, Jun 04, 2015 at 02:53:31PM +0200, Ondřej Bílka wrote: >>> On Thu, Jun 04, 2015 at 02:33:19PM +0200, Jakub Jelinek wrote: >>>> On Thu, Jun 04, 2015 at 12:26:03PM +0000, Joseph Myers wrote: >>>>>> Again is this worth a gcc pass? >>>>> >>>>> This isn't a matter of compiler passes; it's additional checks in >>>>> existing >>>>> built-in function handling. Maybe that built-in function handling should >>>>> move to the match-and-simplify infrastructure (some, for libm functions >>>>> and bswap, already has) to make this even simpler to implement. >>>> >>>> GCC already has a pass that attempts to track known and earlier computed >>>> lengths of strings, and do various transformations and optimizations based >>>> on that, see the tree-ssa-strlen.c pass. Most of that you really can't do >>>> at the glibc headers level. >>>> >>> Yes, I was writing down ideas that I have and this was one of these. I >>> didn't knew it does transformations, just checked that it doesn't use >>> length from stpcpy or in >> >> It does use length from stpcpy in various cases, but stpcpy needs to be >> prototyped. See gcc/testsuite/gcc.dg/strlenopt* for what it does. >>> >>> int foo(char *s) >>> { >>> int l = strlen (s); >>> char *p = strchr (s,'a'); >>> return p+l; >>> } >> >> And what do you want to optimize here? The length from strlen is different >> from the difference between p and s. Furthermore, p can return NULL. >> >> Jakub > > Change that into > > int foo(char *s) > { > int l = strlen (s); > char *p = memchr (s, 'a', l); > return p+l; > } >
Which is still meaningless if 'a' does not appear in s => when the result is NULL + l. In fact, unless 'a' is the first character the result is possibly meaningless anyway, since you can't know that p+l doesn't point more than one beyond the end of the object. Perhaps you just meant to return 'p'? R.