On Tue, Jan 17, 2017 at 7:24 PM, Rafael Avila de Espindola < rafael.espindola at gmail.com> wrote:> Teresa Johnson via llvm-dev <llvm-dev at lists.llvm.org> writes: > > > I was wondering though what happens if we have an alias, which may or may > > not be weak itself, to a non-odr weak symbol that isn't prevailing. In > that > > case, do we eventually want references via the alias to go to the > > prevailing copy (in another module), or to the original copy in the > alias's > > module? I looked at some examples without ThinLTO, and am a little > > confused. Current (non-ThinLTO) behavior in some cases seems to depend on > > opt level. > > > > Example: > > > > $ cat weak12main.c > > extern void test2(); > > int main() { > > test2(); > > } > > > > $ cat weak1.c > > #include <stdio.h> > > > > void weakalias() __attribute__((weak, alias ("f"))); > > void strongalias() __attribute__((alias ("f"))); > > > > void f () __attribute__ ((weak)); > > void f() > > { > > printf("In weak1.c:f\n"); > > } > > void test1() { > > printf("Call f() from weak1.c:\n"); > > f(); > > printf("Call weakalias() from weak1.c:\n"); > > weakalias(); > > printf("Call strongalias() from weak1.c:\n"); > > strongalias(); > > } > > > > $ cat weak2.c > > #include <stdio.h> > > > > void f () __attribute__ ((weak)); > > void f() > > { > > printf("In weak2.c:f\n"); > > } > > extern void test1(); > > void test2() > > { > > test1(); > > printf("Call f() from weak2.c\n"); > > f(); > > } > > > > If I link weak1.c before weak2.c, nothing is surprising (we always invoke > > weak1.c:f at both -O0 and -O2): > > > > $ clang weak12main.c weak1.c weak2.c -O0 > > $ a.out > > Call f() from weak1.c: > > In weak1.c:f > > Call weakalias() from weak1.c: > > In weak1.c:f > > Call strongalias() from weak1.c: > > In weak1.c:f > > Call f() from weak2.c > > In weak1.c:f > > > > $ clang weak12main.c weak1.c weak2.c -O2 > > $ a.out > > Call f() from weak1.c: > > In weak1.c:f > > Call weakalias() from weak1.c: > > In weak1.c:f > > Call strongalias() from weak1.c: > > In weak1.c:f > > Call f() from weak2.c > > In weak1.c:f > > > > If I instead link weak2.c first, so it's copy of f() is prevailing, I > still > > get weak1.c:f for the call via weakalias() (both opt levels), and for > > strongalias() when building at -O0. At -O2 the compiler replaces the call > > to strongalias() with a call to f(), so it get's the weak2 copy in that > > case. > > > > $ clang weak12main.c weak2.c weak1.c -O2 > > $ a.out > > Call f() from weak1.c: > > In weak2.c:f > > Call weakalias() from weak1.c: > > In weak1.c:f > > Call strongalias() from weak1.c: > > In weak2.c:f > > Call f() from weak2.c > > In weak2.c:f > > > > $ clang weak12main.c weak2.c weak1.c -O0 > > $ a.out > > Call f() from weak1.c: > > In weak2.c:f > > Call weakalias() from weak1.c: > > In weak1.c:f > > Call strongalias() from weak1.c: > > In weak1.c:f > > Call f() from weak2.c > > In weak2.c:f > > > > I'm wondering what the expected/correct behavior is? Depending on what is > > correct, we need to handle this differently in ThinLTO mode. Let's say > > weak1.c's copy of f() is not prevailing and I am going to drop it (it > needs > > to be removed completely, not turned into available_externally to ensure > it > > isn't inlined since weak isInterposable). If we want the aliases in > weak1.c > > to reference the original version, then copying is correct (e.g. > weakalias > > and strong alias would each become a copy of weak1.c's f()). If we > however > > want them to resolve to the prevailing copy of f(), then we need to turn > > the aliases into declarations (external linkage in the case of > strongalias > > and external weak in the case of weakalias?). > > > > I also tried the case where f() was in a comdat, because I also need to > > handle that case in ThinLTO (when f() is not prevailing, drop it from the > > comdat and remove the comdat from that module). Interestingly, in this > case > > when weak2.c is prevailing, I get the following warning when linking and > > get a seg fault at runtime: > > > > weak1.o:weak1.o:function test1: warning: relocation refers to discarded > > section > > > > Presumably the aliases still refer to the copy in weak1.c, which is in > the > > comdat that gets dropped by the linker. So is it not legal to have an > alias > > to a weak symbol in a comdat (i.e. alias from outside the comdat)? We > don't > > complain in the compiler. > > The rule should be that the alias to aliasee link is never broken. The > reason being that an alias at the file level is just another symbol with > the same value. > > So if foo is an alias to bar, accessing that foo will always be the same > as accessing that bar, regardless of either of them being weak. I say > *that* foo and *that* bar because symbol resolution may pick another foo > and another bar. >Are you just talking about the comdat case? If this also applies to the non-comdat case, I'm not sure how this works in the following situation (copied from an example in my response just now to pcc): If a module contains the following, and both @x and @y are non-prevailing in that module: @x = weak global ... @y = weak alias @x and the prevailing def for @x is in moduleX with a different value than the prevailing def for @y which comes from moduleY. Just because they are aliased in this module doesn't mean they must be aliased elsewhere, right? For this case (weak non-prevailing alias to a weak non-prevailing def) I think it should eventually become: @x = external global @y = external global Trying to understand how this fits with your comment that "The rule should be that the alias to aliasee link is never broken", unless that is just referring to the case I mentioned just above about when they are both in comdats. Thanks, Teresa> > Cheers, > Rafael >-- Teresa Johnson | Software Engineer | tejohnson at google.com | 408-460-2413 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170118/a83dffed/attachment.html>
Rafael Avila de Espindola via llvm-dev
2017-Jan-18 15:16 UTC
[llvm-dev] Weak symbol/alias semantics
>> The rule should be that the alias to aliasee link is never broken. The >> reason being that an alias at the file level is just another symbol with >> the same value. >> >> So if foo is an alias to bar, accessing that foo will always be the same >> as accessing that bar, regardless of either of them being weak. I say >> *that* foo and *that* bar because symbol resolution may pick another foo >> and another bar. >> > > Are you just talking about the comdat case?No, that is always the case.> If this also applies to the > non-comdat case, I'm not sure how this works in the following situation > (copied from an example in my response just now to pcc): > > If a module contains the following, and both @x and @y are non-prevailing > in that module: > > @x = weak global ... > @y = weak alias @x > > and the prevailing def for @x is in moduleX with a different value than the > prevailing def for @y which comes from moduleY. Just because they are > aliased in this module doesn't mean they must be aliased elsewhere, > right?Correct.> For this case (weak non-prevailing alias to a weak non-prevailing def) I > think it should eventually become: > > @x = external global > @y = external globalWhen dropping @x and @y during IR linking? I agree.> Trying to understand how this fits with your comment that "The rule should > be that the alias to aliasee link is never broken", unless that is just > referring to the case I mentioned just above about when they are both in > comdats.In the above example the "link/connection" is not broken. The original @x and @y still refer to the same data, it is just that neither is used in the final linked object. Cheers, Rafael
On Wed, Jan 18, 2017 at 7:16 AM, Rafael Avila de Espindola < rafael.espindola at gmail.com> wrote:> >> The rule should be that the alias to aliasee link is never broken. The > >> reason being that an alias at the file level is just another symbol with > >> the same value. > >> > >> So if foo is an alias to bar, accessing that foo will always be the same > >> as accessing that bar, regardless of either of them being weak. I say > >> *that* foo and *that* bar because symbol resolution may pick another foo > >> and another bar. > >> > > > > Are you just talking about the comdat case? > > No, that is always the case. > > > If this also applies to the > > non-comdat case, I'm not sure how this works in the following situation > > (copied from an example in my response just now to pcc): > > > > If a module contains the following, and both @x and @y are non-prevailing > > in that module: > > > > @x = weak global ... > > @y = weak alias @x > > > > and the prevailing def for @x is in moduleX with a different value than > the > > prevailing def for @y which comes from moduleY. Just because they are > > aliased in this module doesn't mean they must be aliased elsewhere, > > right? > > Correct. > > > For this case (weak non-prevailing alias to a weak non-prevailing def) I > > think it should eventually become: > > > > @x = external global > > @y = external global > > When dropping @x and @y during IR linking? I agree. > > > Trying to understand how this fits with your comment that "The rule > should > > be that the alias to aliasee link is never broken", unless that is just > > referring to the case I mentioned just above about when they are both in > > comdats. > > In the above example the "link/connection" is not broken. The original > @x and @y still refer to the same data, it is just that neither is used > in the final linked object. >Ok, thanks. But how does that property work the strongalias case from the original email. E.g.: @f = weak global ... @strongalias = alias @f What we had concluded was that it should be transformed into the following when this copy of @f is non-prevailing: @f = external global @f.llvm.1 = internal global ... // Internalized copy of original @f @strongalias = alias @fv.llvm.1 Maybe we are just using different terminology for the same thing, but in this case it seems as though we have broken the link between the original alias @f and aliasee @strongalias? Or is the point that we haven't broken the link between the value in this module of @f (copied to @f.llvm.1) and @strongalias? Teresa> Cheers, > Rafael >-- Teresa Johnson | Software Engineer | tejohnson at google.com | 408-460-2413 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170118/1935324a/attachment.html>