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

    <tr>
        <th>Summary</th>
        <td>
            LTO miscompilation on some rust<->C/C++ calls
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

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

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

<pre>
    The Rust compiler doesn't create IR identical to clang for the same ABI: https://github.com/rust-lang/rust/issues/102174. When doing cross-language LTO, this leads LLVM to do the wrong things when it inlines those calls. This is a regression from 6c8adc505471542be38bd71d1000062daa46d7bc.

STR:
- Create the following files:
`foo.ll` (derived from rustc output, see further below for original source)
```
target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128"
target triple = "i686-unknown-linux-gnu"

%Foo = type { i32 }
define i32 @foo (ptr byval(%Foo) %foo) {
  %1 = load i32, ptr %foo, align 4
  ret i32 %1
}
```

`bar.ll` (derived from clang output, see further below for original source)
```
target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128"
target triple = "i686-unknown-linux-gnu"

define i32 @bar(i32 %0) {
  %2 = tail call i32 @foo(i32 %0)
  ret i32 %2
}

declare i32 @foo(i32)
```
- `llvm-as foo.ll`
- `llvm-as bar.ll`
- `llvm-lto foo.bc bar.bc -filetype=asm -exported-symbol=testFoo -o -`
```
        .text
        .file   "ld-temp.o"
        .globl  bar
        .p2align        4, 0x90
        .type   bar,@function
bar:
        movl    4(%esp), %eax
        movl    (%eax), %eax
        retl
.Lfunc_end0:
        .size   bar, .Lfunc_end0-bar

        .section        ".note.GNU-stack","",@progbits
```

`movl   (%eax), %eax` shouldn't be there, it's dereferencing something that is not originally a pointer.

What happens is that `InstCombine` creates the mess by handling the i32->byval conversion as a i32->ptr conversion:
```
*** IR Dump After InstCombinePass on bar ***
; Function Attrs: mustprogress nofree nosync readnone willreturn
define i32 @bar(i32 %0) local_unnamed_addr #1 {
  %2 = inttoptr i32 %0 to ptr
  %3 = tail call i32 @foo(ptr %2)
  ret i32 %3
}
```
It should be something like
```
%2 = alloca i32
store i32 %0, i32* %2
```
instead of `inttoptr`, or it should bail out (i.e. what happened before 6c8adc505471542be38bd71d1000062daa46d7bc).

Patch for the latter incoming.

Original source:
`foo.rs`
```
// rustc --emit=llvm-ir foo.rs --crate-type=lib --target=i686-unknown-linux-gnu
#[repr(C)]
pub struct Foo(pub u32);

#[no_mangle]
pub unsafe extern "C" fn foo(foo: Foo) -> u32 {
    foo.0
}
```
`bar.c`
```
// clang -O3 -o - -S bar.c -emit-llvm --target=i686-unknown-linux-gnu
struct Foo { int a; };

extern int foo(struct Foo f);

int bar(struct Foo f) {
    return foo(f);
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztV9ty4zYM_Rr7hSONLrZlP_ghcZpOZtJuZzftPmYoibLZpUgNSeXSr-8BJV9z6X5APTLFCwCCByAAlaZ-XT_sBPvaO88q03ZSCctqI5yeZAWmrOBesLuvTNZCe1lxxbxhleJ6yxpjmQez461gV9d3k_yK7bzvHDqT7BbPVvpdX8YQjIHFHhExjn28pHO9cOikSZYWs5h93wmN7SWkV9Y4F-h7vhXs_uHLJNtgP-mYErx27P7-r99ImdoELZ6tARfW9daxZ5IjPZNaSS0cpo0TDNorF7MHkoGHMyu2VjgnjWaNNS1bVEteV_NkPivS-SwrRb4s6yKt0wS_RVZzPlvURVnFk-RmklwN7beHr3Tg0I_YZkCMNGqMUuaZztIAVncgmiySxphYKXTYJFvWwsonUQ8qEDIVM73vek8HdgKCegt5lpUC8gLsxsqt1DCGM72txCRbHUSPTxh6brfCs5p7rvgrhLJJfoMtMxG1UEdEHdo8C03UZUVyPkzPh9RbzEITNaGTZ-NoOXBGeol3uhgG39Jsib3OVPFWdkrs1ZCL5SLq9Q9tnnUES_Uv0Vb3B56xzea3xgQW_9qBt7hmMs_wvhkIatHAyMPcjKAlUDsPvF6fuJqQEiQBIGFh3oy94nrgZjSZBvHK8JrEEO7Ev6feMK7kVrPZnsPiJGE7cI5K7pW5sMBhsuT2A4sPl-l_ix_hOjcokANkI9zJW9tlg2twqcIFP_GDc7Z3jJddGm_cHiax4o2gjzCPGLpKPbURd-xws99ZO_jA5ZpCGCPGsgo0eEUUMsjdcTbuWhaJl85YL-rIvbalUZj2wnm6GBGeo79dut8q9uLFH0ckF28grurIi7aLzQn6q3irTKnQIdQPk10WLgC6M_LQ5GV1Kp-0HBiyDeHV68ojpA4UNH0IfMmqNU9qEEO3UriOQIVIGvCXS7KRCgvvUsGSahjE97Tro9B1crpb7OQ_R93YCVV0cr4DsRj1JnRibbyIf_39z8h5Xv0gjHA6arPhmJ0121J69_m1__wgiAZuZ3pVD9m2DHnDCqKQiAWFY4gUosFfV5RHnGlFyHCg455yGLQ8hAb1ipTWIXl6Yc8y1Hci3vGuEzokvsCMze-08xvTlrhspMqQ7F3IXS3SIuInuHSthg3DhYgm-S8hrKJa0E_ChtzJKZeOixQ3j0unOe8Mn2x8qLS46duOXTXQmp1o9AeHBhAOQ7ED-cidX7Pb0cvYlfeWcitrkTnJKJTRgUtjEUe1ca-6wpXntTYIKc9SKXhNb_XPRRplEFIee61R4tSPvK5Jlzx9NwIBd2_o-HsBVJxgfEKYfxaqxoyTvR-q8s_zzJ0fPYmc6OgmSv4QHxhg1Bpq4Iwh64UF580-9AUMNkNCvDoNl-eiJGwGfJlpyKf2KNAymJG55FE1OnjISUA5FjHKtINjCtK8ob1_tggDTmde_gf31e5QlCruyaGkRvEJJM4ov1zk0ovCDO70UTgNVe1Yo0WRaHFL85sQwqVlAy_mK4t7FI3RW8kSU0MyxPCDBDiKzyfzays6csMN-cF8tHbXl8x521ee3Q7Ogol-SEn59Xm1RDK0eWxRVSDUn0roteONYMgHwmrKxhTQWKPZ4IDU4h6NpRJdZtri1NdZOGPyuSuOxU71HyAOZU_0JQ8JjEXfQuoDrIRqRJj-LGxHYIbaUHvGKUSQgufgjCcniuHIJ6zNWyyJbogJF3TnmAwBZQ_imZg3EE3FOl0s5vN8OV_OpvU6r1f5ik-99Eqs8Y3DWumG7zAeohseus3B5Sb5howCo93if41n-KKZ9latP_nwIizHV4QA-TfS3Om313yZJ8V0t-aLZLbIm6pc5mI5WzWrMq-KIk9n8yIv0qyeKo5y1K3hXvCqqVxnSZalSZolab7IZnG2KuZlLsqC87RYzWsENtHixse0cWzsdmrXQYey3zosKum8Oy4i3KPEEGIvn_f4aLPrLdykln07Dfqug7L_Aum2OCM">