<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/139732>139732</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Missed optimization: trunc not de-duplicated
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
Mark-Simulacrum
</td>
</tr>
</table>
<pre>
This Rust program:
```rust
use std::cell::Cell;
thread_local! {
pub static FOO: Cell<u32> = Cell::new(0xffff);
}
pub fn bar() -> u32 {
FOO.get() + FOO.get()
}
```
results in (at least) a duplicate load + trunc:
First version:
```llvm
%0 = load i32, ptr @"_ZN7example3FOO29_$u7b$$u7b$constant$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$3VAL17h49f9a1072bb59151E", align 4, !range !3, !noalias !4, !noundef !11
%trunc.i.i.i.i.i = trunc nuw i32 %0 to i1
```
Second version:
```llvm
%self3.val.pre.i.i = load i32, ptr getelementptr inbounds nuw (i8, ptr @"_ZN7example3FOO29_$u7b$$u7b$constant$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$3VAL17h49f9a1072bb59151E", i64 4), align 4
%1 = trunc nuw i32 %0 to i1
```
At minimum it'd be great to eliminate the double `trunc`, but combining the two loads also seems worthwhile (it *should* be possible AFAICT to deduplicate those). That would avoid two TLS address lookups in the resulting IR and should allow for further simplification (e.g., dropping some branches).
```llvm
define noundef i32 @_ZN7example3bar17h6628f733c3c7a49fE() unnamed_addr #0 personality ptr @rust_eh_personality {
start:
%0 = load i32, ptr @"_ZN7example3FOO29_$u7b$$u7b$constant$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$3VAL17h49f9a1072bb59151E", align 4, !range !3, !noalias !4, !noundef !11
%trunc.i.i.i.i.i = trunc nuw i32 %0 to i1
br i1 %trunc.i.i.i.i.i, label %"_ZN3std6thread5local17LocalKey$LT$T$GT$4with17h35c29327e034454aE.exit", label %"_ZN3std6thread5local17LocalKey$LT$T$GT$4with17h35c29327e034454aE.exit6.sink.split", !prof !12
"_ZN3std6thread5local17LocalKey$LT$T$GT$4with17h35c29327e034454aE.exit": ; preds = %start
%self3.val.pre.i.i = load i32, ptr getelementptr inbounds nuw (i8, ptr @"_ZN7example3FOO29_$u7b$$u7b$constant$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$3VAL17h49f9a1072bb59151E", i64 4), align 4
%1 = trunc nuw i32 %0 to i1
...
```
Godbolt: https://rust.godbolt.org/z/dPb4bPTTe
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsVk9v27gS_zT0ZRBBGsqWfPDB-eOieOlL0Qbv8C4BJY4sbilS4J-47adfkHLSdFOgu4cCeyiiWGMO5zczP84MLbxXR0O0Y-tLtr5eiRhG63bvhPt08VFNUYvexWnVWflldz8qDx-iDzA7e3RiYnzPyvxsyuVx0QdW7qMn8EEmPd_3pPUiXWXpcrEJoyMhH7TthWZYAWuSAgBgjh34IILq4XB3x_geFsOryJHxG2D8-rySQA2dGLbl52EYBobbM35zvXhJWIOBTjiGLcMtXCSEyPGFv8PdXXGkcN7A8PL7lW9wT1ku0I581MGDMsCwFQE0CR8ShAAZZ616EQi0FTJjBhdN_8zYQTkf4JGcV9a85lHrxylHx3Bd5oQzjuLI8Arm4IDVJUN8-P9_G_osplkTP9zd4faBYR2bjmH9LPTW-CBMyAvySZMEbH-0XVsfHb3ezf-3v62asd4OW1GVDXbdelutqxuGOSih1dFAnUSGlRPmSEng5wVjhVbCJ7F-XopG0pDEqnrKNtNUqKe_nHteAxNPiYCFkmBBVa_P5CP11si_x6snPfDiUehidvTs6688HymQpolMSN-U6VLQPgfDsFXtv_Y81KZOp7F9eTbnzKt_yOo-wKSMmuIEKjBsJHQER0ciJAvSalIm1XoYCaSNnSZgm3Ip-E2ZAuhigN5OnTLKHPO-cLKZaw9CewueaPJwsi6Mp1ElAGxVAIZ7P9qoJcN9cjpb71XC3x_2b6_uk3tJ35otjNYTw20B96MIcEqWIB6tktnf_e1HEFI68h60tZ_inLs3hbM0cwru7QcQRsLiFoTW9gSDdTBEF0Zy4NU0azUkh8rm1qfiWKQkpbPznCC8nQg6J0w_kk_h_LgKJQ3KEDy1QT6FunxZQp1wVTNuNtgODec97xtRb4eb86SKxoiJ5ENKCRjyEmZy3hqhVfjyVJRpIj_Q-PBStYw-H4QLS4v8njM_6wiAzoGqfmCZnGjRkU66hSrug9ws99s6329Vc5te_6EvDOvbe4Z1-n-TPuqTCmPVjHzd45ZjQyWv63Utbgr6nJoNfyn-pvDKfCr8rJ99MaxmZxe28Fy4vyArvgfGL2F2JH0mP03kXJG_x_PPirEoitdD-o2VndWpoWEMYfaps_HA8JAmQHFctIV1R4aHrwwP8n1Xd-_v72kld1xu-VasaFc1dVPVddny1bhD2bbDBttW8LKt1pWUnaw2A7Zt37WE5UrtsMR1ua54xeu25EVbt13Ju66VclP1YsPqkiahdJEmXvK9Ut5H2lV823Bc5bL2-acnoqETZG0iaH29crtkdNHFo2d1qZUP_htMUEHT7p3yniTYOahJfc3zOKV_Zs4GkHTxfDnIVXR69z01RxXG2BW9nRge8lReXhezs39QHxgeckie4eEc8-MO_wwAAP__boRJpA">