http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60395
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |lto, wrong-code Status|UNCONFIRMED |NEW Last reconfirmed| |2014-03-03 CC| |hubicka at gcc dot gnu.org, | |rguenth at gcc dot gnu.org Ever confirmed|0 |1 Known to fail| |4.7.2, 4.8.2, 4.9.0 --- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- Confirmed on x86_64 with using -mstringop-strategy=libcall. Shorter single-file testcase: void *memset(void *dest, int ch, __SIZE_TYPE__ count) { char *p = (char *)dest; while (count--) *p++ = (char)ch; return dest; } int main () { volatile int dummy[10] = {0}; return dummy[0]; } > gcc t.c -Os -mstringop-strategy=libcall -flto -fno-builtin `memset' referenced in section `.text.startup' of /tmp/ccdDUr5m.ltrans0.ltrans.o: defined in discarded section `.text' of /tmp/ccApnJzK.o (symbol from plugin) collect2: error: ld returned 1 exit status 1 t.o 2 177 b0e6a56d4c94b3b5 PREVAILING_DEF_IRONLY memset 180 b0e6a56d4c94b3b5 PREVAILING_DEF main and then IPA kills the memset definition because it's unused at IPA time and it isn't a builtin. Then expansion re-introduces a call to memset an we use the linker resolution and try to bind it locally which obviously fails (even though a fallback is available in libc). IMHO even with -fno-builtin IPA needs to preserve certain function bodies we may introduce calls to late (memset, memcpy, memmove are the obvious ones), much like we have special_function_p which matches on the function name and not only the builtin property. Or we need to simply _not_ mark those definitons as non-builtin as we introduce calls to them late. Or we need to fixup things at the linker side (we introduce a call to the _builtin_ memset but we discarded a non-builtin memset). The special_function_p-like hack is probably easiest but not the robustest solution. Not sure if we can adjust the linkers idea of where a def resides at all. Honza?