<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/67342>67342</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Missed optimization
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
ojeda
</td>
</tr>
</table>
<pre>
From: https://github.com/rust-lang/rust/issues/116150
With LLVM 17.0.1:
```llvm
%"core::result::Result<u16, i32>" = type { i16, [3 x i16] }
%"core::result::Result<u16, i32>::Ok" = type { [1 x i16], i16 }
%"core::result::Result<u16, i32>::Err" = type { [1 x i32], i32 }
define i64 @f(i32 %err) unnamed_addr #0 {
%r = alloca %"core::result::Result<u16, i32>", align 4
%_3 = icmp slt i32 %err, 0
br i1 %_3, label %bb1, label %bb2
bb2: ; preds = %start
%ok = trunc i32 %err to i16
%1 = getelementptr inbounds %"core::result::Result<u16, i32>::Ok", ptr %r, i32 0, i32 1
store i16 %ok, ptr %1, align 2
store i16 0, ptr %r, align 4
br label %bb3
bb1: ; preds = %start
%2 = getelementptr inbounds %"core::result::Result<u16, i32>::Err", ptr %r, i32 0, i32 1
store i32 %err, ptr %2, align 4
store i16 1, ptr %r, align 4
br label %bb3
bb3: ; preds = %bb1, %bb2
%3 = load i64, ptr %r, align 4
ret i64 %3
}
```
optimizes to:
```llvm
define i64 @f(i32 %err) unnamed_addr #0 {
%_3 = icmp slt i32 %err, 0
%err.lobit = lshr i32 %err, 31
%r.sroa.4.0.insert.ext = zext i32 %err to i64
%r.sroa.4.0.insert.shift = shl nuw i64 %r.sroa.4.0.insert.ext, 32
%0 = shl i32 %err, 16
%1 = select i1 %_3, i32 0, i32 %0
%r.sroa.3.0.insert.shift = zext i32 %1 to i64
%r.sroa.3.0.insert.insert = or i64 %r.sroa.4.0.insert.shift, %r.sroa.3.0.insert.shift
%r.sroa.0.0.insert.ext = zext i32 %err.lobit to i64
%r.sroa.0.0.insert.insert = or i64 %r.sroa.3.0.insert.insert, %r.sroa.0.0.insert.ext
ret i64 %r.sroa.0.0.insert.insert
}
```
```asm
f: # @f
mov eax, edi
shr eax, 31
mov rcx, rdi
shl rcx, 32
mov edx, edi
shl edx, 16
xor esi, esi
test edi, edi
cmovns esi, edx
or rsi, rcx
or rax, rsi
ret
```
But if the `trunc` is away from the store:
```llvm
%"core::result::Result<u16, i32>" = type { i16, [3 x i16] }
%"core::result::Result<u16, i32>::Ok" = type { [1 x i16], i16 }
%"core::result::Result<u16, i32>::Err" = type { [1 x i32], i32 }
define i64 @f(i32 %err) unnamed_addr #0 {
%r = alloca %"core::result::Result<u16, i32>", align 4
%ok = trunc i32 %err to i16
%_3 = icmp slt i32 %err, 0
br i1 %_3, label %bb1, label %bb2
bb2: ; preds = %start
%1 = getelementptr inbounds %"core::result::Result<u16, i32>::Ok", ptr %r, i32 0, i32 1
store i16 %ok, ptr %1, align 2
store i16 0, ptr %r, align 4
br label %bb3
bb1: ; preds = %start
%2 = getelementptr inbounds %"core::result::Result<u16, i32>::Err", ptr %r, i32 0, i32 1
store i32 %err, ptr %2, align 4
store i16 1, ptr %r, align 4
br label %bb3
bb3: ; preds = %bb1, %bb2
%3 = load i64, ptr %r, align 4
ret i64 %3
}
```
it ends up without a `select`:
```llvm
define i64 @f(i32 %err) unnamed_addr #0 {
%err.lobit = lshr i32 %err, 31
%r.sroa.4.0.insert.ext = zext i32 %err to i64
%r.sroa.4.0.insert.shift = shl nuw i64 %r.sroa.4.0.insert.ext, 32
%0 = shl i32 %err, 16
%r.sroa.3.0.insert.shift = zext i32 %0 to i64
%r.sroa.3.0.insert.insert = or i64 %r.sroa.4.0.insert.shift, %r.sroa.3.0.insert.shift
%r.sroa.0.0.insert.ext = zext i32 %err.lobit to i64
%r.sroa.0.0.insert.insert = or i64 %r.sroa.3.0.insert.insert, %r.sroa.0.0.insert.ext
ret i64 %r.sroa.0.0.insert.insert
}
```
```asm
f: # @f
mov eax, edi
shr eax, 31
mov rcx, rdi
shl rcx, 32
shl edi, 16
or rcx, rdi
or rax, rcx
ret
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWElv2zgU_jX0hYjARYt90CGO61OLAeYwcywoibbYUqJBUln66wckJVvy0jgJOoNBLRSWxLd9fO_x9YuYMWLbcp6DZAmS1Yx1tlY6V994xWaFql7ytVYNoPewtnZnAL0HZA3Ieits3RVRqRpA1roz9k6ydts_A7IWxnTcALLGOMUJAmgF0H34_VvYGn7-_NcXiLMIRdj5HIlBisI_KR-bfokkgJBSae506b3mppM2PP_ZPz90OAXkAQpKAP0ECIGArqB92XEIsiUUQQqSJYXP_i1ZQZCt3h3Ay_74fhIIJEu8j-D1cfrxQJ-0vhiJkiESJaNI_rfiG9FyKNIYghhtAJl7JZJw53ABu7ZlDa--sqrSEBCKnOdgCp2a9iGZlKpk8F1lcC9Mim0L45Hfr9Q7FmWzg0ZaOEb1ANGgWWgocNB365IVXLrXosBH72S8a_dK7yGgS7jTvDI-FiCJsUzbEQr1PWRUd205ggCt8vU7KGKvt-WWS97w1u6shqItVNc65x9pHrfovLlcDzVEwwMeIBirNA-d5FCPjPAhv-RUGx27P6pEocc5pNMc4qtySH5FakK7vyk3kwbqrc413yE5-CPJoS45b7pOMtk38bh9fUbD0ZCKVe7cvgJScxtON0kGhPsJMAzSMXK1s6IRP7iBVr0-eD86Pq485mEpkqoQNmze1PpImeLxWIqMViyKIxSJ1nBtI_4cLH-4h6OjnA7ZOmtparEJtqaWsO2ehnyeDeKhjKuF9qZTvGfmh-GSl3Yy0SYt7bydIKXnkI53iad7PG8abt5W6csb9BH6prwQ_wQgerUIfWEvlAJdh_JkM1OYUxRnTselaNccmv0iM_3B2PjZSGg4Fn20cDXq0d85e3YQeSWmctfaI_mhr6fmuvRifWoux_JDLx7MeXUpcjDt5YcODdez6oEZ4c3NYG65scFOnPVbNuqxNQfD6nkq7_1CHeQOeZDvBSEV2hw51tz-pCrLzkKxgbbmEKTI_ycOUgSFgeyJvcCNVo0X-ol_I5m_H8m8mt79K2z0Y2ThmHb9rxjpjZDeCOmlKS4s5K4y3Q4-CVurzkLm5nkgS075l7PU67nn-6nnf8M930Aj0Y1G3mjkRNzTvWOauCdtFzwfk7o92ztlc7Mqp9WCLtiM5zhdJGmSEURndT4vCGNlVm0wYohtaMZSHi_iJONlPE_SciZygghFC5LgJKGERul8ztM5TRc4QxVeZCBGvGFCRm5MREpvZ_6LZJ5mNCYzP0aN_-ZJSMufoBe6CZ-sZjp3NndFtzUgRlIYaw5erLCS51-EMbyC_R_TzArVzjot8598I_XjKtzudlp9c8Nt9JnU4_onAAD__wqiwe8">