https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91287
--- Comment #25 from rguenther at suse dot de <rguenther at suse dot de> --- On Wed, 31 Jul 2019, hjl.tools at gmail dot com wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91287 > > --- Comment #19 from H.J. Lu <hjl.tools at gmail dot com> --- > (In reply to Richard Biener from comment #17) > > (In reply to Richard Biener from comment #16) > > > (In reply to Richard Biener from comment #15) > > > > Honza probably knows where we output the LTO symtab and why we do not > > > > put > > > > undefs for builtins there. > > > > > > #include <math.h> > > > double y, z; > > > void foo (); > > > int main() > > > { > > > volatile double x = atan2 (y, z); > > > foo (); > > > } > > > > > > > gcc-8 -c t.c -flto > > > > gcc-nm t.o > > > U foo > > > 00000000 T main > > > 00000000 C y > > > 00000000 C z > > > > > > where's the > > > > > > U atan2 > > > > > > ? > > > > For > > > > double atan2 (double x, double y) { return x + y; } > > > > it doesn't appear either, this CU has an empty symbol table... > > > > I do remember quite some "funs" with builtin handling though, so the > > current handling may be the least bad of all choices... > > [hjl@gnu-cfl-1 pr91287]$ cat foo1.c > #include <stdlib.h> > > float > atan2f (float x, float y) > { > abort (); > return x * y; > } > [hjl@gnu-cfl-1 pr91287]$ cat foo.c > float > atan2f (float x, float y) > { > return x * y; > } > [hjl@gnu-cfl-1 pr91287]$ cat bar.c > #include <math.h> > > extern float x, y, z; > > void > bar (void) > { > x = atan2f (y, z); > } > [hjl@gnu-cfl-1 pr91287]$ cat main.c > #include <math.h> > > extern void bar (void); > > float x, y = 1, z =1; > > int > main (void) > { > x = atan2f (y, z); > bar (); > return 0; > } > [hjl@gnu-cfl-1 pr91287]$ make > cc -O3 -c -o foo.o foo.c > ar rc libfoo.a foo.o > cc -O3 -fpic -c -o bar.o bar.c > cc -O3 -fpic -c -o foo1.o foo1.c > ld -shared -o libfoo1.so foo1.o # --version-script foo1.v > ld -shared -o libbar.so bar.o libfoo1.so > cc -flto -O3 -o x main.c libfoo.a libbar.so libfoo1.so -Wl,-R,. > cc -O3 -o y main.c libfoo.a libbar.so libfoo1.so -Wl,-R,. > ./y > ./x > make: *** [Makefile:9: all] Aborted > [hjl@gnu-cfl-1 pr91287]$ > > Since atan2f isn't referenced in IR, linker doesn't extract atan2f from > libfoo.a. atan2f is resolved to definition in libfoo1.so later. The odd thing is that if you omit libfoo1.so then it will consider libfoo.a later but not when it can resolve from libfoo1.so. That's a bit inconsistent but arguably the bug is with GCCs symbol table creation of the LTO IR.