Some optimizations, e.g. SimplifyLibCalls, can replace functions with others as part of the lowering, e.g. printf => puts.
The new symbols don't have the isUsedInRegularObj flag set so they don't get included in the final symbol table (and dynamic symbol table), and the dynamic linker gets confused.
davide@foogoo:~/llvm/build/bin % ./clang blah.c -o blah -flto -fuse-ld=lld -Wl,-L/lib
davide@foogoo:~/llvm/build/bin % ./blah
Segmentation fault (core dumped)
davide@foogoo:~/llvm/build/bin % ./llvm-nm ./blah | grep puts
% cat blah.c
#include <stdio.h>
int main(void)
{
printf("blah\n"); return (0);
}
My proposed fix is to set the flag in addCombinedLtoObject() once we see the new symbols. I'm working on a testcase now, but I would like to hear if this sounds reasonable to you.