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

    <tr>
        <th>Summary</th>
        <td>
            Possible Undefined Behavior when `FunctionImporter` imports from different modules.
        </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>
    Originally from https://github.com/rust-lang/rust/issues/104377. I have observed that, when Rust performs its "Thin LTO" pass, `FunctionImporter` sometimes imports _**incompatible**_ definitions/declarations. I don't believe this issue is Rust-specific.

Given the number of moving parts involved, I do't currently have a simple repro, but consider the following case:

Assume we start with some module **`X`** (in pseudo-LL):

```ll
define void @outer(ptr noundef %0) {
  call void @inner(ptr noundef %0)
}

define void @inner(ptr noundef %0) { ... }
```

Dead argument elimination comes along and does:

```ll
define void @outer(ptr noundef %0) {
  call void @inner(ptr poison)  ; `noundef` is gone.
}

define void @inner(ptr %0) { ... }  ; `noundef` is gone.
```

So far so good. But now Thin LTO comes along and runs on a module **`Y`** that doesn't contain or reference `@outer` at all. Maybe it already contains a

```ll
declare void @inner(ptr noundef %0)
```

or maybe that gets (transitively) imported from some module **`Z`**. Now suppose that `@outer` also gets (transitively) imported. Suddenly we have in **`Y`**:

```ll
define available_externally void @outer(ptr noundef %0) {
  call void @inner(ptr poison)  ; Passing `poison` to `noundef` parameter!
}

declare void @inner(ptr noundef %0)
```

---

I'm not really familiar with how things are supposed to work, but I'm currently thinking that when importing a `define x` from a module `A` into a module `B`, then all globals referenced by `x` that are `define`d in `A` must _not_ reference any declarations about them already present in `B`.

---


_**Background:**_ https://reviews.llvm.org/D133036 (not yet submitted) eliminates function calls where `undef` (or `poison`) is passed to a parameter when that parameter is marked `noundef`. In the example above, it would eliminate the call to `@inner`. I've observed this causing mis-compiles in the Rust compiler.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy9VtuO2zYQ_Rr5ZWDBl_XtwQ_rLFIESJOgTYG2LwvKGtnsUqRAUnb89z1DaW3vZrNJgbbAri3R5MyZM2eGU7jytP7o9U5bZcyJKu9q2sfYhGx6m03e4m-n474t8q2r8eLbEIdG2V3_jC8dQssBD-PRzXSxyOkd7dWByRWB_YFLinuFfW_ouGdLv-AQNewr5-tAOgbKJpPPe23p_eePeKRGhSC7s_nobWu3UTv7rm6cj-yxRMHVHHXNOJtWA91nEyC91RYIGxV1YbhbuaeSK221mBB8JW-N8iq9CsrS2WyyiFSw0QzAca9hVaLBZwI6DA1vdaW3eTa6y0a33edP-oBA4p7JtnXBnlxFtTtouwN4QaTtwRlELmGIm-Rl23rPNoLjxI6igAAMk-fGO9lZtNgEaLqESbFeOWPcUcxuVWDJxxWIW-CsmY5MIcIpHZGlRA6glC3sdhyAst_x371gbQmim8Bt6Ybv32eT1TOrsjX9GdMtJAaZDk6XlN2MXCtpmCyb6Mm61uJnGJ3B_oqyxaY7Q8BrzPmMtvZbZ3qni7trDM9cvnJcXFKe53Sx8Ij_2uAdq5KU34EvGwnJriF2UQHoFiEp48CxsiVSxeF_ZqRxOogOV0TZdCOq762I2CHDnbOc_1OeXuDnB8y_xN2vjirlISzsdGVOG4jUuiM9VuxXFPrWBgK16isd_nHRoXSERHZXgFB9VLDnPKqhYpTJlgXqmV5gxQFQmNPP6lSgPuXNI6-nx8PA8J20SfH_kKxeoQMI6wQgRbDj1L6W0SuUbURbMCehvetM6Hypm75YlH-eycjpA_gMbdO40Nt9HroR-r_jK6df27Jki_6CnpBaDBh9gfwf1Lc6KG0Ueuk9fwGO7nb4j0T_CS1f2hxQ9L8g6uieqRW9VaH3i5HxNwri30jxcDi8fn0HhdY4HiHN7oZUtTYaNZE67h65w71hd9AfXPdpLAX90fmHx77eWblcAXLkQUJO-U4XY5dIWVMSeJ-GLxJ5ktGloOYJOdILJ9erm5TjN3J3WCkW2hlXQDyXoiqpOMnOZDW5FtBnb_KQVNN7qOWuvkfs91d1qeyJrm9SUgXkIE7rc002noP02s6W4Mpfobj77K_xjdo-7LxkKw0g3T3-dCDxfNB8DLkxhzp3XkaRu_F0OprOpUAkVSeOSEVR6xjlFl6dmz5aVdUPFUmdQbjvKDjrDDZQ5tdaTHUW0mTSpVZdxNglL3F5WcPmWvkHbH4iYQwd3dzAX1S6-0HdgSVl6GdH15ryAjTtSwXUFcJZz8kM5PR0woLHrWpTFdU6DGUU0kaGpM5hmrr6RZ8PeD2ez5c34_l0OhuU62m5mq7UIOpoeP3JoRhR9_Sb7VRR0obRT7TrY_3GYPY4jiWxlrpKeom9PEM-aL1ZvzJYSjL7ryEGor94-2S2nC1Xi_lgv57Nb1Q1XkyqlRqr8Xy0WBU84vmqmE8ZARUD9Cw2YZ3NNhgmLR-7gQ7P2exuoNeT0WQyHo9vRsvZcnaTL3jFxXg62i4r2FquwDLXaHxnbQ38OkEq2l3Aj0aHeBHeQPrWzjInd7Cv2rh3fv1Z1x8-DJLjdQL-NxuTkDI">