I currently don't have a small compilable test case, except a build tree from a large project. But what happened was code like this f() { static void *addr[] = { &&label1, &&label2, .. }; /* labels defined in the code */ } The LTO partitioner would put addr into a different ltrans unit than f. But the assembler output of addr contains direct references to the code labels in the assembler of f. This results in lots of assembler errors for undefined labels.
Yep, this is a known problem. We do not represent labels in symbol table and thus LTO partitioner has no clue about them. I would be interested to see the example that fails - theoretically the problematic static variable should always end up in the same partition as the function using it, because that function is no inline and no clone and should not get duplicated. So kernel & friends should fail only with -flto-partition=1to1 not with ballanced/none/one algorithms. I plan correct solution - I already implemented labels for symtab some time ago but I would like to re-do it on the new API. The poor-man's class hiearchy in C was not very pretty and a lot of code is still not updated to nots assume two basic types of symbols (variables and functions). With Martin Liska we are updating the APIs and once it is done I will add symbols for non-local labels and const_decls.
Created attachment 33023 [details] lto.config Test case git clone https://github.com/andikleen/linux-misc -b lto-linus-3.15 Build with the attached kernel config (copy to .config in the build dir) and 4.9 -Andi On Fri, Jun 27, 2014 at 11:04:00PM +0000, hubicka at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61635 > > Jan Hubicka <hubicka at gcc dot gnu.org> changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > Status|UNCONFIRMED |ASSIGNED > Last reconfirmed| |2014-06-27 > CC| |hubicka at gcc dot gnu.org > Assignee|unassigned at gcc dot gnu.org |hubicka at gcc dot gnu.org > Ever confirmed|0 |1 > > --- Comment #1 from Jan Hubicka <hubicka at gcc dot gnu.org> --- > Yep, this is a known problem. We do not represent labels in symbol table and > thus LTO partitioner has no clue about them. I would be interested to see the > example that fails - theoretically the problematic static variable should > always end up in the same partition as the function using it, because that > function is no inline and no clone and should not get duplicated. So kernel & > friends should fail only with -flto-partition=1to1 not with ballanced/none/one > algorithms. > > I plan correct solution - I already implemented labels for symtab some time ago > but I would like to re-do it on the new API. > The poor-man's class hiearchy in C was not very pretty and a lot of code is > still not updated to nots assume two basic types of symbols (variables and > functions). With Martin Liska we are updating the APIs and once it is done I > will add symbols for non-local labels and const_decls. > > -- > You are receiving this mail because: > You reported the bug. >
> > git clone https://github.com/andikleen/linux-misc -b lto-linus-3.15 > Build with the attached kernel config (copy to .config in the build dir) and > 4.9 Aha, we still compile kernel with -fno-toplevel-reporder? That probably could drag variables out of their contextes. Will have to take a look. Honza
Yes it uses -fno-toplevel-reordering to avoid the problems with the initializer reordering. I tried some workarounds for this, but nothing worked so far. Likely would need a noreorder attribute.
Also I forgot to state: the git tree above now has a workaround (disabling LTO for that file). If you want to reproduce revert the latest commit first.
> Yes it uses -fno-toplevel-reordering to avoid the problems with the initializer > reordering. > > I tried some workarounds for this, but nothing worked so far. Likely would need > a noreorder attribute. Actually I think other chance to make this to fail is when the address/value of the local static is propagated by ipa-prop into some extra function... Perhaps as a workaround in 4.9 we may disable such a propagation. Honza
Still happens with current trunk and with newer LTO Linux kernels (4.0-rc*)
I am testing fix that is small enough for GCC 5 (and backportable to release branches I guess)
Created attachment 35177 [details] partitioner This is patch I am testing
We already have ealrier PR for this. *** This bug has been marked as a duplicate of bug 50676 ***