<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=http://email.email.llvm.org/c/eJzVVV1vmzAU_TXk5aoITEjDAw_Nsk2TJk2a9j4ZfAlujR3ZJl3363dt0i5p1rTdx8MQimPux7m-nHtojLirv_TSwefReWiNwKS4SrJ1kl0li2y6LZmmR50GNw4JW3LygoQtknIlC5aU64RVcJEUb4G2kFyuJn-gi5NPRh7kvoqb_HATYye4y_Uj3Gm7RdsZOzhozKiFg7bH9saB0YC87YFby--Aty06B1KDsQJtCm-7Dlsvd6juQHrwlmunuEcH3oAzA_pe6g0oeYNAf93PU__Ns8sOeKpQU1RwSoo13ZAdO4Vry7VsE5ZHR5aBGT2YDqjqDdIDCk6KgxDqFaBy-ARA_hxA_vsAbwIAew6AvRjgJNGoHe_ic0LeoP866vjKUVDqLBbBfmXKnzaxaLrn1x7-POum3_eo0RJrBHDncGjU3el0cDc86sTo-rBa_u3YQOzz0eBkwt7E5ch-jdOaflytsq_zY2M7bOEgOD8XWp4NZY9CGzwILY6Ng9nFFeksFCpuabxg6y0Q-a2Qsd_zhxG-j-JCnIt6rX9EWZ5Ebc3-WO2jPlv0Z97plVI08RaJYoztWcug5Y60gUhjtJBeGs0VKUdLv8BJaaw1FnquhQqq0ZFf8IGBW2IYEEJrlKAlPUSKutqaUQmgHputl4P8Tu4NJTZDI3XI5XuMxAjiRdJk9LQljx3a4MAf6h11kKtYFhUbOuUMmbgPSSzNalBFMocckfxBJEP-3niaT9-n8KGDW9rzHQYd3JgJNPiEA0z6T3ljGnqqQUgSUovaSxoDOoa_RZySPlj2oaGmFD6eCuo_ktKnhOjFmhs59DrdDdfrtfcU6Fn9PQJ6QcJn9Xaf8H8Q4JmoC1EVFZ_x0ffG1r79zq9v-Gy0qu6930ZusXd0b6TvxyalaaKNUrv75WJrzTV9_2krnRvDsLwriywvZ32dLdll1TFsllVTFEW1aMsqWzas64pquWBipnhDjamJk9RHjbcQU4SeluvZn1cga5YR1fKszJfzeclShrxoqKISq7ysFnkyz3DgUqUhT2rsZmbrmLIZN46MSpJa_DTSl0luNGIsmCr00iusP01qw4NMhSGbBOdAQxpiCr0gN4vl1bG2HwN-xE0>53015</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Optimization: combine unlikely branches
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
tczajka
</td>
</tr>
</table>
<pre>
This Rust code:
```rust
fn sum(a: &[i32]) -> i32 {
a[0] + a[1] + a[2]
}
```
performs bounds checks on each array access in order. Effectively it translates to something like this:
```rust
fn sum(a: &[i32]) -> i32 {
if a.len() == 0 {
panic!("0 out of range");
} else if a.len() == 1 {
panic!("1 out of range");
} else if a.len() <= 2 {
panic!("2 out of range");
} else {
unsafe { a.get_unchecked(0) + a.get_unchecked(1) + a.get_unchecked(2) }
}
}
```
Generated assembly:
```asm
push rax
test rsi, rsi
je .LBB0_4
cmp rsi, 1
je .LBB0_5
cmp rsi, 2
jbe .LBB0_3
mov eax, dword ptr [rdi + 4]
add eax, dword ptr [rdi]
add eax, dword ptr [rdi + 8]
pop rcx
ret
```
All three "panic" cases unconditionally call an error handling function marked `cold`.
This could be optimized by combining the tests into one test covering all three unlikely cases, so that there is only one check on the hot path. If we have to go into the cold code, only then differentiate between the different cold cases. Like this:
```rust
fn sum(a: &[i32]) -> i32 {
if a.len() <= 2 {
if a.len() == 0 {
panic!("0 out of range");
} else if a.len() == 1 {
panic!("1 out of range");
} else {
panic!("2 out of range");
}
} else {
unsafe { a.get_unchecked(0) + a.get_unchecked(1) + a.get_unchecked(2) }
}
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzVVt9v0zAQ_mvSlxNR4jTd-pCHlQJCQkJCvCPHvjTeHLuynY7x13N2utGurNsQPBBFdZ378Z0v331ta-Vd87VXHr6MPoCwErPqKivWWXGVLYrpdmSaHnUG_Dhk7JKTF2RskdUrVbGsXmdsCW-y6h3QFrKL1eQPdHHyKciD3FdpUx5uUuwEd7F-hDttt-g66wYPrR2N9CB6FDcerAHkogfuHL8DLgR6D8qAdRJdDu-6DkVQO9R3oAIEx43XPKCHYMHbAUOvzAa0ukGgr_7Xqf_m2VUHPNdoKCo6ZdWabiiOneK15UaJjJXJkRVgxwC2A6p6g_SAgrPqIIR6Bag9PgFQPgdQ_jnA2wjAngNgLwY4STQaz7v0nJA3GL6NJr1ylJS6SEWw35nKp00sme75tYc_z7rp8wMadMQaCdx7HFp9dzod3A-POjH6Pq6Ofz82EPtCMniVsbdpObJf47Tmn1ar4tv82CiGLRwEl-dC67Oh7FFoiweh1bFxsLu0Ip2FQuUtjRdsgwMiv5Mq9Xv-MML3UVzKc1Gv9U8olydRW7s_lnjUZ4fhzDu90pom3iFRjLE9axkI7kkbiDTWSBWUNVyTcgj6BE5K45x10HMjdVSNjvyiDwzcEcOAEITVkpb8ECnpqrCjlkA9ttugBvWD3FtKbIdWmZgr9JiIEcWLpMmaaUseO3TRgT_UO5ooV6ksKjZ2ylsy8RCTOJrVqIpkjjkS-aNIxvy9DTSfoc_hYwe3tOc7jDq4sRNo9IkHmPSf8qY09NSAVCSkDk1QNAZ0jHCLOCV9sOxDY005fDoV1H8kpU8J0Ys1N3Hodbobr9dr7ynQs_p7BPSChM_q7T7h_yDAM9lUclkt-SyooLH5PA0OjxMX-TLNzsE4tHRowvKz0emmD2GbyMfe071RoR_bnEJoo_Xufnmzdfaa_iDQVnk_xml6X1dFWc_6RhTispasZhcXiwWvsBQtE3VRt4t2KWtWzzRvqXMNkZYabfAWUorY9Ho9Uw0riEllUZeX83nNcoa8apcdq3FZ1stFmc0LHLjSeawjt24zc00qqR03noxakRj8MtIPj9oYxARH-fkYeuuaIH7w6xs-S9BNKv0nYKevHg">