<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - lld + ThinLTO + fprofile-generate causes duplicate symbol errors"
   href="https://bugs.llvm.org/show_bug.cgi?id=37422">37422</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>lld + ThinLTO + fprofile-generate causes duplicate symbol errors
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>tools
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>lto
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>pirama@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Filing issue reported in llvm-dev thread
<a href="http://lists.llvm.org/pipermail/llvm-dev/2018-May/123131.html">http://lists.llvm.org/pipermail/llvm-dev/2018-May/123131.html</a>.


The duplicate symbol errors are for __llvm_profile_filename and
__llvm_profile_raw_version.  IIUC, these are supposed to be weak symbols but
Thin LTO seems to break this in some way.  This does't happen with gold or no
LTO or full LTO.

$ cat > a.c
extern int foo();

int main() {
  return foo();
}

$ cat > b.c
int foo() {
  return 0;
}

$ clang a.c -fprofile-generate -flto=thin -c
$ clang b.c -fprofile-generate -flto=thin -c
$ clang a.o b.o -fprofile-generate -flto=thin -fuse-ld=lld
ld.lld: error: duplicate symbol: __llvm_profile_filename
<span class="quote">>>> defined at a.c
>>>            lto.tmp:(__llvm_profile_filename)
>>> defined at b.c
>>>            lto.tmp:(.rodata.__llvm_profile_filename+0x0)</span >

ld.lld: error: duplicate symbol: __llvm_profile_raw_version
<span class="quote">>>> defined at a.c
>>>            lto.tmp:(__llvm_profile_raw_version)
>>> defined at b.c
>>>            lto.tmp:(.rodata.__llvm_profile_raw_version+0x0)</span >
clang-7: error: linker command failed with exit code 1 (use -v to see
invocation)

Teresa Johnson>> From adding save-temps, it looks like lld and gold are giving
different resolutions to the symbols, which is presumably creating this issue:

Peter Collingbourne>> The problem is that ThinLTO is not dropping the
non-prevailing definitions, and they end up being emitted into the object file
for b.o.

$ ../ra/bin/llvm-dis -o - b.o0.0.preopt.bc | grep __llvm_prof
$__llvm_profile_raw_version = comdat any
$__llvm_profile_filename = comdat any
@__llvm_profile_raw_version = constant i64 72057594037927940, comdat
@__llvm_profile_filename = constant [19 x i8] c"default_%m.profraw\00", comdat

lld ignores comdats in LTO object files because it expects all comdats to have
already been resolved. So we see this error. 

We are supposed to drop non-prevailing symbols here, but for some reason we do
it only for weak symbols. That's not correct in ELF where comdat symbols can be
both strong and non-prevailing.
<a href="http://llvm-cs.pcc.me.uk/lib/LTO/LTO.cpp#290">http://llvm-cs.pcc.me.uk/lib/LTO/LTO.cpp#290</a>

This patch fixes the reproducer but it leads to other test failures that would
need to be looked at.

diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 7e8b9b3c6390..ee11d07d6b8e 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -287,7 +287,7 @@ static void thinLTOResolveWeakForLinkerGUID(
         recordNewLinkage) {
   for (auto &S : GVSummaryList) {
     GlobalValue::LinkageTypes OriginalLinkage = S->linkage();
-    if (!GlobalValue::isWeakForLinker(OriginalLinkage))
+    if (GlobalValue::isLocalLinkage(OriginalLinkage))
       continue;
     // We need to emit only one of these. The prevailing module will keep it,
     // but turned into a weak, while the others will drop it when possible.
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp
b/llvm/lib/Transforms/IPO/FunctionImport.cpp
index 246d75caefa2..61790c9fc435 100644
--- a/llvm/lib/Transforms/IPO/FunctionImport.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp
@@ -765,7 +765,7 @@ void llvm::thinLTOResolveWeakForLinkerModule(
       return;
     }

-    if (!GlobalValue::isWeakForLinker(GV.getLinkage()))
+    if (GlobalValue::isLocalLinkage(GV.getLinkage()))
       return;
     // Check for a non-prevailing def that has interposable linkage
     // (e.g. non-odr weak or linkonce). In that case we can't simply</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>