<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi,<div class=""><br class=""></div><div class="">I believe we should get it right (and simpler) if (when…) we move to the representation we discussed last spring: <a href="https://llvm.org/bugs/show_bug.cgi?id=27866" class="">https://llvm.org/bugs/show_bug.cgi?id=27866</a></div><div class=""><br class=""></div><div class="">Our conclusion was that we should always have alias pointing to private anonymous and nothing else, so when we currently have:</div><div class=""><div class=""><br class=""></div><div class="">@a = global i32 0</div><div class="">@b = alias @a</div><div class=""><br class=""></div><div class="">It should always become:</div><div class=""><br class=""></div><div class="">@0 = private i32 0</div><div class="">@a = alias @0</div><div class="">@b = alias @0</div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">— </div><div class="">Mehdi</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div><blockquote type="cite" class=""><div class="">On Jan 13, 2017, at 3:21 PM, Peter Collingbourne <<a href="mailto:peter@pcc.me.uk" class="">peter@pcc.me.uk</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hi Teresa,<div class=""><br class=""></div><div class="">I think that to answer your question correctly it is helpful to consider what is going on at the object file level. For your test1.c we conceptually have a .text section containing the body of f, and then three symbols:</div><div class=""><br class=""></div><div class="">.weak f</div><div class="">f = .text</div><div class="">.globl strongalias</div><div class="">strongalias = .text</div><div class="">.weak weakalias</div><div class="">weakalias = .text</div><div class=""><br class=""></div><div class="">Note that f, strongalias and weakalias are not related at all, except that they happen to point to the same place. If f is overridden by a symbol in another object file, it does not affect the symbols strongalias and weakalias, so we still need to make them point to .text. I don't think it would be right to make strongalias and weakalias into copies of f, as that would be observable through function pointer equality. Most likely all you need to do is to internalize f and keep strongalias and weakalias as aliases of f.</div><div class=""><br class=""></div><div class="">If we're resolving strongalias to f at -O2, that seems like a bug to me. We can probably only resolve an alias to the symbol it references if we are guaranteed that both symbols will have the same resolution, i.e. we must check at least that both symbols have strong or internal linkage. If we cared about symbol interposition, we might also want to check that both symbols have non-default visibility, but I think that our support for that is still a little fuzzy at the moment.<br class=""></div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Peter</div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Fri, Jan 13, 2017 at 2:33 PM, Teresa Johnson <span dir="ltr" class=""><<a href="mailto:tejohnson@google.com" target="_blank" class="">tejohnson@google.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="">Hi Mehdi, Peter and David (and anyone else who sees this),<div class=""><br class=""></div><div class="">I've been playing with some examples to handle the weak symbol cases we discussed in IRC earlier this week in the context of D28523. I was going to implement the support for turning aliases into copies in order to enable performing <wbr class="">thinLTOResolveWeakForLinkerGUI<wbr class="">D on both aliases and aliasees, as a first step to being able to drop non-prevailing weak symbols in ThinLTO backends.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">Example:</div><div class=""><br class=""></div><div class=""><div class="">$ cat weak12main.c</div><div class="">extern void test2();</div><div class="">int main() {</div><div class="">  test2();</div><div class="">}</div><div class=""><br class=""></div><div class="">$ cat weak1.c</div><div class="">#include <stdio.h></div><div class=""><br class=""></div><div class="">void weakalias() __attribute__((weak, alias ("f")));</div><div class="">void strongalias() __attribute__((alias ("f")));</div><div class=""><br class=""></div><div class="">void f () __attribute__ ((weak));</div><div class="">void f()</div><div class="">{</div><div class="">  printf("In weak1.c:f\n");</div><div class="">}</div><div class="">void test1() {</div><div class="">  printf("Call f() from weak1.c:\n");</div><div class="">  f();</div><div class="">  printf("Call weakalias() from weak1.c:\n");</div><div class="">  weakalias();</div><div class="">  printf("Call strongalias() from weak1.c:\n");</div><div class="">  strongalias();</div><div class="">}</div><div class=""><br class=""></div><div class="">$ cat weak2.c</div><div class="">#include <stdio.h></div><div class=""><br class=""></div><div class="">void f () __attribute__ ((weak));</div><div class="">void f()</div><div class="">{</div><div class="">  printf("In weak2.c:f\n");</div><div class="">}</div><div class="">extern void test1();</div><div class="">void test2()</div><div class="">{</div><div class="">  test1();</div><div class="">  printf("Call f() from weak2.c\n");</div><div class="">  f();</div><div class="">}</div></div><div class=""><br class=""></div><div class="">If I link weak1.c before weak2.c, nothing is surprising (we always invoke weak1.c:f at both -O0 and -O2):</div><div class=""><br class=""></div><div class=""><div class=""><div class="">$ clang weak12main.c weak1.c weak2.c -O0</div><div class="">$ a.out</div><div class="">Call f() from weak1.c:</div><div class="">In weak1.c:f</div><div class="">Call weakalias() from weak1.c:</div><div class="">In weak1.c:f</div><div class="">Call strongalias() from weak1.c:</div><div class="">In weak1.c:f</div><div class="">Call f() from weak2.c</div><div class="">In weak1.c:f</div><div class=""><br class=""></div><div class="">$ clang weak12main.c weak1.c weak2.c -O2</div><div class="">$ a.out</div><div class="">Call f() from weak1.c:</div><div class="">In weak1.c:f</div><div class="">Call weakalias() from weak1.c:</div><div class="">In weak1.c:f</div><div class="">Call strongalias() from weak1.c:</div><div class="">In weak1.c:f</div><div class="">Call f() from weak2.c</div><div class="">In weak1.c:f</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">$ clang weak12main.c weak2.c weak1.c -O2</div><div class="">$ a.out</div><div class="">Call f() from weak1.c:</div><div class="">In weak2.c:f</div><div class="">Call weakalias() from weak1.c:</div><div class="">In weak1.c:f</div><div class="">Call strongalias() from weak1.c:</div><div class="">In weak2.c:f</div><div class="">Call f() from weak2.c</div><div class="">In weak2.c:f</div><div class=""><br class=""></div><div class="">$ clang weak12main.c weak2.c weak1.c -O0</div><div class="">$ a.out</div><div class="">Call f() from weak1.c:</div><div class="">In weak2.c:f</div><div class="">Call weakalias() from weak1.c:</div><div class="">In weak1.c:f</div><div class="">Call strongalias() from weak1.c:</div><div class="">In weak1.c:f</div><div class="">Call f() from weak2.c</div><div class="">In weak2.c:f</div></div><div class=""><br class=""></div><div class="">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?). </div><div class=""><br class=""></div><div class="">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:</div><div class=""><br class=""></div><div class=""><div class="">weak1.o:weak1.o:function test1: warning: relocation refers to discarded section</div></div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Teresa</div><span class="HOEnZb"><font color="#888888" class="">-- <br class=""><div class="m_1265033782169285673gmail_signature"><span style="font-family: times; font-size: inherit;" class=""><table cellspacing="0" cellpadding="0" class=""><tbody class=""><tr style="color:rgb(85,85,85);font-family:sans-serif;font-size:small" class=""><td nowrap="" style="border-top:2px solid rgb(213,15,37)" class="">Teresa Johnson |</td><td nowrap="" style="border-top:2px solid rgb(51,105,232)" class=""> Software Engineer |</td><td nowrap="" style="border-top:2px solid rgb(0,153,57)" class=""> <a href="mailto:tejohnson@google.com" target="_blank" class="">tejohnson@google.com</a> |</td><td nowrap="" style="border-top:2px solid rgb(238,178,17)" class=""> <a href="tel:(408)%20460-2413" value="+14084602413" target="_blank" class="">408-460-2413</a></td></tr></tbody></table></span></div>
</font></span></div></div>
</blockquote></div><br class=""><br clear="all" class=""><div class=""><br class=""></div>-- <br class=""><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr" class="">-- <div class="">Peter</div></div></div>
</div>
</div></blockquote></div><br class=""></div></body></html>