<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/59347>59347</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            `FunctionImporter` links to wrong function with `private` linkage
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          TimNN
      </td>
    </tr>
</table>

<pre>
    Assume two modules contain two _different_ functions `@inner` with `private` (or `internal` linkage). If a function `@outer` that references `@inner` gets imported across module boundaries the wrong definition of `@inner` may be used in places.

I haven't managed to repro this with `clang` so my IR may be bad, though the fact that changing a `noinline` attribute changes the result makes me relatively confident that this is an actual bug.

Repro (run as `llvm-lit main.ll -a` to see the output):

```ll
; other.ll

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define i32 @outer(i32 %0) {
 %r = call i32 @inner(i32 %0)
  ret i32 %r
}

define private i32 @inner(i32 %0) #0 {
  %r = mul i32 %0, 2
  ret i32 %r
}

; Comment this to change the result of `main`.
attributes #0 = { noinline }
```

```ll
; main.ll

; RUN: opt -module-summary %p/main.ll -o %t.main.bc
; RUN: opt -module-summary %p/other.ll -o %t.other.bc
; RUN: llvm-lto -thinlto -o %t.summary %t.main.bc %t.other.bc
; The `inline` pass isn't strictly necessary but makes the problem more obvious.
; RUN: opt -passes=function-import,inline -summary-file %t.summary.thinlto.bc %t.main.bc -S

define i32 @main() {
  %a = call i32 @outer(i32 1)
  %b = call i32 @inner(i32 1)
  ; This _should_ be `2 * 3` but is either `2 * 2` or `3 * 3` depending on the
  ; `noinline` configuration in `other.ll`.
  %c = mul i32 %a, %b
  ret i32 %c
}

define private i32 @inner(i32 %0) {
  %r = mul i32 %0, 3
  ret i32 %r
}

declare i32 @outer(i32 noundef)
```

`@inner` in `other.ll` multiplies by **`2`**. `@inner` in `main.ll` multiplies by **`3`**. The multiplication in `@main` _should_ be `2 * 3`, but is either `3 * 3` (if `@inner` in `other.ll` is `noinline`) or `2 * 2` (if `@inner` is not `noinline`).

The correct result of `2 * 3` can be achieved by commenting the `noinline` and adding `-passes=inline` when running `opt` on `other.ll`.

cc @teresajohnson
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykVstu2zoQ_Rp6M5AhU7ZsL7xwEgTIpou2dx1Q1FhiS5ECH0nz9xdDPfxI0tviAgEj0uSZB88cjvBeNQbxwDZ3bPOwEDG01h2-q-7Ll0Vl67fD0fvYIYRXC52to0YP0poglElrz7U6ndChCc9wikYGZY0HVuZsnStj0LEyh1cVWlrrnXoRAWmJ8Z11tKZMQGeEpkWtzE_RIOP7JTydQMyII6CNYQAMrQjgMBmW-M5eg8GD6nrrAtYgpLPej95DZaOphVPoIbQIr86aBmo8KaOSJXu6RevEG1QI0WMNykCvhUS_ZPkDy4_D-ASteEHD-DZAJ4xosIZgwWHvLIRW-TkDUgvTEKi30L3B09cJvRI14_cQWhubNnl2EjIMgcpWmEaZBgRBGKuMViZlUYTgVBUDDnvGmBz6qMmTn-iho7kWQb2gfqOrO6kazYicfFMehAEhQxQaqthchfY1xcD4zkUDImVa65cu04oMKLPUGjKR7sSCR0wO2Bj6GBjfs-J4CUaJTX9ajwvFHdjQolvOK2kMwjUYoBZBaPFmYwBWPADjHLOOFUfMer7NWXEseBpourqe0le5TkOmpo_Tjg6t-C4zO_oopzPlOvu24jvG-ZX94FSvcbL9a1c-l-ssmp_GvppMKxN_ZY2J86lhTFxCUAWHmbJ8l6Z8kzO-B7a9G7bSikvwUmg9HRmId3Vk3A4OA4zLbrS5ffjA-Fhov0EExov8wpOzK13UcN54D_yPjdNt3tuuG-ilPFFi4OUlLYcCI-6wMh-5NvPYj35Rxrd3MHEdzpYmCv0nr0Z23jr49Z8vrDiC7QNkgyRkPnadcG8UWM_440xr4v0mLNO8kn8DMXF6xhgWPgAZiilYyEKrTPoYj1xAzj58Bva9xUFLJ2HohafCHiTJB6dk0G9gUKL3BFrFSR_oZnpnK40ddNYh2OpF2TgL3E28BIyeFQ-TNGeDzjJ-P17VlIvspKh2LkJZjiHOgUxRZd8-L6BEFCrN_Q1bxbvCuay11UXVML6pfltlV5tTOpWHZ9_aqOtnUmdW5sT7IxSUXEqe8oCK7uH8G6ffhketOG-usUdTk3pbQ8m-tHOj5kmcm-hEeohUevVmdZxrJcUjb0tVUKlSoB9Uq_y_UvEHKlH8hURJLdyHAmnobcbTfBufFvvF6_wuTeRaUL2mF76i8jnSX5nT9QyT5e0LP2BMgvE5RHEBQSU3bZOXNzZxtsw_pxBl7B2LLkhD-XjXh7yPVPkbCtFt2VtKfgzmwdjw_vjV408xSuscynCt3hfFIIWh8IRsFb5gTfmSwxtAnA-DMF31LKYGUaeKYGV-FpTzjtcWDbhozLjH9iGV1icFMYxSEpsCOvTih22Nt2ZRH4p6X-zFAg-rcpvzbVkWq0V72O-2m3Ildye5qyuxkhWvi4rnYo9brDarYqEOPOd8xfMNX62LzWq5FZJv9rUQZbkvJC_ZOsdOKL0k_V5a1yyU9xEPm32x3i60qFD71FNzbvAV0o_UJ2weFu6QNL-KjWfrXCsf_BklqKDxwMr8cZTXp6GLdVN7nB7VoWmdm-MP2uuxk15Epw9tCL2nTow_Mv7YqNDGailtx_gj2R3_Zb2zP1AGxh-Tt57xxxTNvwEAAP__I4SRcw">