On Sat, Aug 12, 2017 at 10:08 PM, Andrew Pinski <pins...@gmail.com> wrote: > On Sat, Aug 12, 2017 at 9:21 PM, David Wohlferd <d...@limegreensocks.com> > wrote: >> Environment: >> gcc 6.1 >> compiling for 64bit i386 >> optimizations: -O2 >> >> Consider this simple bit of code (from >> https://stackoverflow.com/a/45656087/2189500): >> >> #include <stdio.h> >> >> int getStringLength(const char *pStr){ >> >> int len; >> >> __asm__ ( >> "repne scasb\n\t" >> "not %%ecx\n\t" >> "dec %%ecx" >> :"=c" (len), "+D"(pStr) >> :"c"(-1), "a"(0) >> ); >> >> return len; >> } >> >> int main() >> { >> char buff[50] = "hello world"; >> int a = getStringLength(buff); >> printf("%s: %d\n", buff, a); >> } >> >> This code works as expected and prints out 11. Yay. >> >> However, if you add "buff[4] = 0;" before the call to getStringLength, it >> STILL prints out 11 (when optimizations are enabled), when it should print >> 4. >> >> I would expect this kind of behavior if the asm were in 'main.' But it has >> always been my understanding that function calls performed an implicit >> memory clobber. The fact that this clobber goes away during inlining means >> that code can stop working any time the compiler makes a different decision >> about whether or not to inline a function. Ouch. >> >> And before somebody asks: Adding "+m"(pStr) does not help. > > But does adding: > "+m"(*pStr) > > Help? > > > "+m"(pStr) Just says pStr variable changes, not what it points to.
I should ask why are you using inline-asm for this? strlen will have the best optimized version for your processor anyways. Thanks, Andrew > Thanks, > Andrew Pinski > >> >> The result is that (apparently) you can NEVER safely pass a buffer pointer >> to inline asm without using the memory clobber. If this is true, I don't >> believe it is widely known. >> >> Given how 'heavy' memory clobbers are, I would hope that only pointers that >> have 'escaped' the function would get flushed before a function call. But >> not flushing *anything* seems very bad. >> >> dw >>