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

    <tr>
        <th>Summary</th>
        <td>
            Also outline conditions that pick which cold BB to go to
        </td>
    </tr>

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

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

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

<pre>
    This rust example https://rust.godbolt.org/z/nddKM8G61
```rust
pub fn demo(x: &[u32]) -> u32 {
    x[0] + x[1] + x[2]
}
```

And this C++ example https://cpp.godbolt.org/z/8sM48xddx
```rust
unsigned demo(std::vector<unsigned>& v) {
    return v.at(0) + v.at(1) + v.at(2);
}
```

Produce very similar assembly
```nasm
        test    rsi, rsi
        je      .LBB0_4 ; <-- Note branch
        cmp     rsi, 1
        je      .LBB0_5 ; <-- Note branch
        cmp     rsi, 2
        jbe     .LBB0_3 ; <-- Note branch
        mov     eax, dword ptr [rdi + 4]
        add     eax, dword ptr [rdi]
        add     eax, dword ptr [rdi + 8]
        pop     rcx
        ret
.LBB0_4:
        lea     rdx, [rip + .L__unnamed_1]
        xor     edi, edi
        xor     esi, esi
        call    qword ptr [rip + core::panicking::panic_bounds_check@GOTPCREL]
        ud2
.LBB0_5:
        lea     rdx, [rip + .L__unnamed_2]
        mov     edi, 1
        mov     esi, 1
        call    qword ptr [rip + core::panicking::panic_bounds_check@GOTPCREL]
        ud2
.LBB0_3:
        lea     rdx, [rip + .L__unnamed_3]
        mov     edi, 2
        mov     esi, 2
        call    qword ptr [rip + core::panicking::panic_bounds_check@GOTPCREL]
        ud2
```

That `panic_bounds_check` is cold, as is the `__throw_out_of_range_fmt` in the C++ example.

Because those three jumps all lead to cold blocks and the first two are actually subsets of the last one, it would be nice if the "which cold call specifically" jumps could be moved out of the main part of the method so they don't need to get decoded or use icache space.

For example, it could be structured something like this:
```nasm
        cmp     rsi, 2
        jbe     .LBB0_3 ; <-- Just the superset branch in the main part
        mov     eax, dword ptr [rdi + 4]
        add     eax, dword ptr [rdi]
        add     eax, dword ptr [rdi + 8]
        pop     rcx
        ret
.LBB0_4:
        lea     rdx, [rip + .L__unnamed_1]
        xor     edi, edi
        xor     esi, esi
        call    qword ptr [rip + core::panicking::panic_bounds_check@GOTPCREL]
        ud2
.LBB0_5:
        lea     rdx, [rip + .L__unnamed_2]
        mov     edi, 1
        mov     esi, 1
        call    qword ptr [rip + core::panicking::panic_bounds_check@GOTPCREL]
        ud2
.LBB0_3:
        test    rsi, rsi
        je      .LBB0_4 ; <-- Then the specific checks moved later
        cmp     rsi, 1
        je      .LBB0_5 ; <-- Then the specific checks moved later
        lea     rdx, [rip + .L__unnamed_3]
        mov     edi, 2
        mov     esi, 2
        call    qword ptr [rip + core::panicking::panic_bounds_check@GOTPCREL]
        ud2
```

(I don't know enough about the encodings to know if specifically that is the right way -- maybe rearranging the blocks to have forward branches would be better or something -- but hopefully that gets the idea across.)

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztV9tu4zYQ_Rr5hYghS5YvD36Ik91F22y7KPIuUOTYYkKRKi--9Os7pGTHdtx0NyiwQLuGbZrk3M5wPEesNN8vHmthifHWEdjRppVAaudam-S3SfYR32FruNa80tINtVnj0p_4UZz_8nn2aTJK0vskvU0mafcO4t1S6yuyUoRDo5NstkODJMkmSbH0eZYU90k2JzdJ_oHglCTTZadE8LVDmRQlUHwZJ6PTSdTtfE7vL5z30_h9qzhxAdsdagbl6_BY215BN7Ofx7Md57u_ReeVFWsF_IDPOh5s5rcbYE6bJL87SCBGxE02AfAZTgPOG0U2Q-rQQBr3Mc5-PrqYZzhP8uXXQP9iNPcMyAbMnljRCEkNodZCU8n9hZ6itnkJKbwcYC2E8KxIsrs4nO0_QTcOH5bLtBwTDAo_dzc35FftgFSGKlafq7CmJScmR28ZLN5hMLswWMGJwfxrDDZ6E0egu2CQb7XhpHWGYMUZLuJBjI-Vd9CinL-l9a3y0cvslVare7Bsd76BBdQt9EcRCvBMQALtBHn0F7yINnoZPpSlV4o2wMvRK487bbo4eUxvGK7vd-mHyxJhVMow_nEGsHfNtIHur9JSJdizUOuTaVlpr7gtWQ3sORmnn357_HL3-4eHVzF6np2CL94JPntl-FgK_FqxHnevlvJ3AJ6_E3j-T8CzN4Fn3xH41ab3WFNHcO2KzUlKkAeYljxETm2YuRqCdFm62uhtqb0r9arEzrCGctW4qKOi1AV_DE-dLoFRbwHldPw2AOTJN60lIR94EMhBOnomldTsGdcjLQFZCYNt1m01oQYIZc6jBnZrX1lwluhVlJIUhbSCELdwZKt9sAQEIQIRnUySZdtasLpzEw_CtsDESoTfe9zuQ2IHbTxKJC6EfHDTUMTaUvOyAIiIE6vDbE-4Vkk2dUQBREBrcMh7TPNgxpCQAXSGyUbPlJ2n6CMK9KnrURzjsM54BG4geAousTCIFM8QiftY129w1Xt54OfwvBOAWt-CwYz3pHA482NCfrDED5b4b7LE-x_zHmvo_iWHNkNiNLbvK5I6MP_O89-3e_p_ch9eD346NulnpbcElPbrmtAqdPmQQVDYrtG5Df07iiB9nPIESiGB9sxoxLpGuqF7gqfQ0D02UgPUBHoMPTqI9HyG1mq6QT7TZksRftdHwb5wVQUOjynwxEuTR6sVBlbrFlb-6HwdmC_YFhyPkTKjrR2Ga08EOeCLnM_zOR044SQsbiXSE8KTQgGmWXHhhFa2M9ViqskJLS6XkbeQz_TAG7k4vwSuhat9NWS6wYmUm8Nw0xr9hPc5nAprPVj8URTTYj6oF6yAyXg2n_NiVcyL0ZgVFcWFCZ-Nx2wyHg0krUDaBdYCUrACTHgwgb_xcAdikaVZlhbZPC3GxWg6LKpJClOWUZZmLF-NsBgAWUgOQxzhZjowixhS5dcWN6Wwzr5s4u0uXDYhukP71COBm4Vl2rmGNYPoexFj_wtcr4QE">