https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91287

--- Comment #22 from Xiong Hu XS Luo <luoxhu at cn dot ibm.com> ---
(In reply to Xiong Hu XS Luo from comment #21)
> (In reply to H.J. Lu from comment #19)
> > (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.
> Thanks for your test case.
> If remove the libfoo1.so when build x, it will link libfoo.a. And run x will
> not abort.  
> 
> luoxhu@genoa pr91287 $ ~/local/gcc_t/bin/gcc -flto -O3 -o x main.c libfoo.a
> libbar.so  -Wl,-R,.
> luoxhu@genoa pr91287 $ ./x
> 
> Since x can link the libfoo.a if libfoo1.so not exists, not quite understand
> why "atan2f isn't referenced in IR"?
> 
> Acutually my test case shows that binary built with LTO can link libmass.a
> first when use gcc, but failed to link libmass.a if use gfortran(link
> libm.so finally).
> 
> PS: My test case (gcc LTO link libmass.a first) doesn't match with your case
> result(gcc LTO link libfoo1.so instead of libfoo.a).

BTW, the link sequence is quite important, switch libbar.so and libfoo.a, then
x will link atan2 in libfoo.a instead of libfoo1.so, which matches my test
case:

~/local/gcc_t/bin/gcc -flto -O3 -o x main.c libbar.so libfoo.a libfoo1.so 
-Wl,-R,.

Reply via email to