<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/131457>131457</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[AArch64] Opportunity to materialise constants using `sub 0, imm, lsl 12`
</td>
</tr>
<tr>
<th>Labels</th>
<td>
backend:AArch64,
llvm:optimizations,
missed-optimization
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
Kmeakin
</td>
</tr>
</table>
<pre>
Instead of materialising `-(4095 << 12)` with a MOVZ+MOVK pair, it can be done in a single instruction by subtracting from the zero register:
```c
uint32_t src32(uint32_t x) { return 0 - (4095 << 12); }
uint32_t tgt32(uint32_t x) { return x - (4095 << 12); }
uint64_t src64(uint64_t x) { return 0 - (4095 << 12); }
uint64_t tgt64(uint64_t x) { return x - (4095 << 12); }
```
```asm
src32:
mov w0, #4096
movk w0, #65280, lsl #16
ret
tgt32:
sub w0, w0, #4095, lsl #12
ret
src64:
mov x0, #-61440
movk x0, #65280, lsl #16
ret
tgt64:
sub x0, x0, #4095, lsl #12
ret
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJycVF1vqzgQ_TXDyyiRGRsIDzzkQ5FWV1d9uw_7sjLgEm8BR_bQpv31KyDp0irqbi-yZONhzjk-g0eHYJvemAKSHSSHSA98cr740Rn9ZPuodPVr8Ucf2Oga3SN2mo23urXB9g1CKlZAGyXyBEHuQe4xJqAcUoEvlk-o8efDrz-Bdj8ffv3As7YeaI-WsdI9lgZr1xu0PWoc8dpxHdgPFVvXY_mKYSjZ64pHskfvOuSTwTfjHXrT2MDGg9yCmEYq5lGB2A62Z0l_MQZfSQLavG9cgHKEbIfe8OB7FLjCu0eQO4TssMTihr_Guvwn1hUuVbO0VF3hpo3fkzalcsNfY_0PaTf_PtmpQwdiO_s4eY3Xp3PP0_wixpoCSSXy9GP86UM8TWgzrdvQju_x8mtveCaeXf7AFIZywbTkS5ZwdA9udvmu8MsNaJXGSok70i_flv6Z6yZ9Rrp8Q_qiHFFdyDqXuY5MEWeKRCI2WRqdCkOxzoRMVSoN5bKiTOXVJjFluanVpnyMbEGCEiHjJE5EHKu1qpIqkbGqJCkhMwFKmE7bdt22z93a-SayIQymiGWskixqdWnaMPUGolJXT6avQW63W1-dxh-OgPZANCaD3Loz286-6fH2hvdgZ0Mw9WoZHGPJIfLFmLgqhyaAEq0NHP7VwZbbqSvdyJIDPpzPzvPQW35FdotmZLByfWDdc8Dh1ppG7yfDbdfdzI4JUhENvi1OzOcwFouOQMfG8mko15XrgI7TceZpdfbub1Mx0HEyJgAdr948F_RPAAAA___gLnA0">