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

    <tr>
        <th>Summary</th>
        <td>
            Missing non-null reference optimization
        </td>
    </tr>

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

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

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

<pre>
    Example code:
```cpp
int* GetPtr();

void ProcessNullptrCase();

void Foo()
{
 int& ref= *GetPtr();
    int* ptr= &ref;
    if( ptr == nullptr )
 ProcessNullptrCase();
}
```
Produces following IR:
```llvm
define dso_local void @_Z3Foov() local_unnamed_addr #0 {
  %1 = tail call noundef ptr @_Z6GetPtrv()
  %2 = icmp eq ptr %1, null
  br i1 %2, label %3, label %4

3:
  tail call void @_Z18ProcessNullptrCasev()
  br label %4

4:
  ret void
}

declare noundef ptr @_Z6GetPtrv() local_unnamed_addr #1

declare void @_Z18ProcessNullptrCasev() local_unnamed_addr #1
```
And following assembly:
```asm
_Z3Foov: # @_Z3Foov
        push    rax
        call _Z6GetPtrv@PLT
        test    rax, rax
        je      .LBB0_2
 pop     rax
        ret
.LBB0_2:
        pop     rax
 jmp     _Z18ProcessNullptrCasev@PLT     # TAILCALL
```

The result code contains `nullptr` check for result of `GetPtr` call. But this check is obsolete, since this call result is dereferenced and references in C++ should be never null.

I suppose the problem is in some missing `nonnull` notation. As i know there is such notation for function arguments and `load` instructions. Maybe such notation for `call` instruction result is just missing. Note that generally it isn't correct to use such hypothetical notation for all calls returning pointers. It is correct only for calls which unconditionally lead to dereference of pointer result.

Compiler explorer link: https://godbolt.org/z/x4z8GaoWq. Clang version is 17.0.1, options are `-O2 -g0`.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyMVk1v4zgM_TXKhajhyLGTHHJI0s2gQGe2WAywwF4KWWZitbLokeS06a9fSHZapx-YKYoYMh8fyUeatnBOHQziiuUbll9PROdrsivxWB_J1bKelFSdVn89i6bVCJIqZNmapdcsXbMi7f9l2_Z3lPGMr-Eb-jtvGV8wvmTZZkDH3yOpCu4sSXTuR6d16-1WOPwauyMajL1lPkAgxirA4p5l18D4-tOoAABDVq23PbKIPmPAnvFFsAPLrgPG9JnBa9g_SHl-_U6V_nhnqeokOtiT1vSkzAFu_vkoodbHpr9V4V4ZhMrRvSYpNEQZ2Cy9_y_bER37uBBt950xosHqXlRVyDZL4U0gYDyfhorAC6VBCq3BUGcq3Pe1BsqiV-041jh68uipZNMC_urxPJ8yvo3inIGlBTWN8GDRokQdTtnFaTZuavZaO4zyeqtxuvgo9bvsSvsF92zEbdFH1vfdGTSWWlj8nRxfiDz9jOqPKvgN4eXkrE01GhrhHDalPn0cHeGGyTkPSLYOpOOReZ308Nd2rg5XK54vDbETIw1m6d3tz0uIR-fPvnz7keIB-2tyu9mk93wwttTCpxEt-v7GGf_WvyHXD54PTX_nK51j0hERNPi5vrndrm9vPxW4__1ZI1h0nfZxu4Ek44UyDliRDnuAFSnIGuUj7MmewbQPiGHpBIDQOoFN58HXyg145YBKRxo9Br2cMhIHexB7oFIOKrS4R4tGYgXCVPB6dKAMbBnfML4BV1OnKygRDB7RxmcxGVdzA65rW3IhCkJrqdTYhADKgKMGoVHOhXkK1ZGJz3KRgiEvvCKTwNqBgkdDT4HAYnB1naxfEVGCfWdkPAh76Bo03sWcwx4jUQVCZZy3XQS5BL6LU4mf8IR3h-gzGDmMZHnonD-nnMAP8qEu4eGABq3Q-gQq4Azj89A-a1F68ASdG8LVp5Z8jV6FTXoRO-gfgrswhZ01QZSWlPFoXQI3MfyZkYw-Rafe4alWsobOSDKVCoQxE42iCrFHrQxDMnAORV00a0tNqzRawOdWk0ULWpnH8PzW3rcuPA18x_juQFVJ2idkD4zvXhjfPc9eFt8E_fsrga0W5gBHtC5UphxM50maxE1NbdQfwn5iRXr1N4erQ5j_ZFKtsmqZLcUEV9N5ms_m02yZT-qVXOJiXuQ55ot0L4v5kuc8nfOFLHLkyNOJWvGUz9LpdJ4WaTbNk6rMctzPloui4pwvBZul2Ailk_BKCylPlHMdruaLbLmcxMXt4scG5wafIBoZ5-Hbw66Cz1XZHRybpVo5795YvPIaV9-H8TVkrsLwwkjr1qtGvcQOTzqrV-9EVL7uykRSw_guvm77y1Vr6QGlZ3wXc3GM72Ku_wcAAP__W1_G3g">