<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=http://email.email.llvm.org/c/eJylVdtu2zAM_RrlhbAhy0kcP_ghTbGiGLYBRX9AtmhHhWxlkpym-_pRdi9psHUbFtiKRFLUIXlE11Y9VfsQDp7lWyY-0dNZVVsTUus6Wv2g97PclDffb9oHxq8Z387j_V57kG2LTfBwQNda18uhQaAJbO--5AKwr1EpVOCffMDep-f7v1roZQjo4HEvA7RGdh5uodnLoUMmdnEuBxjwSCYdBgh7BId-NEEPHbA1N8rRCMHC6BHIlq2udN-j0jIg2Lb1GNjqmonN-wAVuTSWIKfS9Wlj-yizzdjjEGTQdojrUfNlkdPsgV6yS-SgkrAf-zrRgw9ubKKlJyXBSJLXc5P53ISJMoXbAB4p8IhRmkf55KFGoAiVoawctYyo8RScpMg67WM2enucwicjOBPPbt9lcGcoVZAtU57ymI_k2w9IesJKY3MYWX5N8yKoXkdxraNAHhpPps9uaDI90vezhA6H-HNZhMBEnq1nhfFmVvComEdSi1lrnTvb9rp5ycuX7cqdbac6PfvJYn0mi_o0GYBxF9he2IZU4_Bo4Tz70NjRqJhTqmKtB0qqHmKuwRNHDIKxkkQXnEj_Ofo0Tf82jgvc83iHycFZNTaRuTsCqzCy8f2GZl5TAFR1qYi2carViagErLia1fH0hkIPcLSG2EpBkhkT22fp9fZ-C1Rpgr_5jWH0x08ZzzjLz7w6DKMbJgfxItG5FNOLASs-iu9mt4M5QPTTPVXotaNq2DEcxvesjbaZeOOs_1_OfkxNqdSvtH-k5lz9P7JzoapclXkpF3IMe-uqFo0-PdgB_WJ05rK1auog9XPLMeb48hfZ8UCNlJba-xFjW1nlgtzvK8k5Nq3KVmvEkq_zdrPKuCoLvtlgWZbNwsgaja8IORNiwEeYXNCc0C_-H4GuBBeCZ1lBOV1SVys2dS2zZoVrUdTFWrAlx15qk0Y_8auxcNXksh47T0pDDcy_KaX3uhsQJ8CEMOhgsJo_GF9toF4eL8nlnV1MqKoJ0k9C1ffD>53260</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
ARM32 Not using immediate offset
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
felixjones
</td>
</tr>
</table>
<pre>
https://godbolt.org/z/Ka89GqGfj
This affects performance for ARM32 embedded systems.
No matter what flags I change, I can never get the resulting `ldr` to use an [immediate offset](https://developer.arm.com/documentation/dui0473/j/arm-and-thumb-instructions/ldr--immediate-offset-). It seems to always be handled via an extra register move, and a register offset.
Clang 14.0.0 `-Oz -marm -mcpu=arm7tdmi -mabi=aapcs`
```asm
mov r1, #16
lsl r0, r0, #2
orr r1, r1, #4096
ldr r0, [r0, r1]
bx lr
```
These two instructions could be combined into a single load immediate offset.
```asm
mov r1, #16
...
ldr r0, [r0, r1]
```
Re-producing C code:
```c
int read(int idx) {
const volatile int* const DATA = ( const volatile int* ) 0x1010;
return DATA[idx];
}
```
GCC produces the desired output.
GCC 12.0.0 `-Os -marm -mcpu=arm7tdmi -mabi=aapcs`
```asm
lsl r0, r0, #2
add r0, r0, #4096
ldr r0, [r0, #16]
bx lr
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJylVcFu2zAM_RrlQtiw5SRODj6kKVYUwzqg6A_IEu2okK1MktO0Xz_Kbrsk2NoNCxxFIimSj3xmaqueq10Ie8-KDeNf6Gmtqq0JqXUtnV7o-1Ws1jc_bppHll2zbDOtDzvtQTQNyuBhj66xrhO9RKANbO6_FRywq1EpVOCffcDOp6f37yx0IgR08LQTARojWg-3IHeib5HxbdyLHno8kEmLAcIOwaEfTNB9C2yZGeVohWBh8AhkyxZXuutQaREQbNN4DGxxzfjqHKAil8ZSyqlwXSptF2VWDh32QQRt-3gedDYvC9o90pfsEtGrJOyGrk5074MbZLT0pKQ0kuQ9bjLFTRhfp3AbwCMBjzkK8ySePdQIhFAZqspBi5g1HoMThKzVPlajs4cRPhnBiXhye1bBraFSQT5PszSL9Ui-v0DSUa60yv3Aimval0F1OoprHQViLz2ZvrqhzfgI300SCg7x4_KYAuNFvpwUxptJkUXFtJKaT1rr3Mm198vzbP12XbmT69SnVz957M9oUR9HAzDuIrc3tiH1ODxZOK0-SDsYFWtKXax1T0XVfaw1eOKIQTBWkOiCE-k_o0_T9G9xXOQ9rfeY7J1Vg4zM3VKyCiMbzy_I6UwAqOtCEW3jVqsjUQlYeTWpY3RJ0AMcrCG2EkgyY3zzKr3ePGyAOk3pr_5gGP1lxzzLM1aceHUYBtePDuKLRHEJ05sBKz_Cd7PdwgQQ_fieKvTaUTfsEPbDOWujbc5_cdb_L2c_pqZQ6nfaT6k5df9Tds5UVah1sRazoIPBahp8dzbQTIrNvuTebHDmct5qGiv16xwy5vD2EynzSNOVjtr7AeOsWRScYu6qdbmSOMaVzVyVi2KxrhvJxVLlciFXxcyIGo2vCA7jvMcnGF3QniDNdMUzzrM8L6lMcxpU5aquBd3EJS_rcsnZPMNOaJPGPOIfwcxVY0r10HpSGppJ_pdSeK_bHnEMR_7FEHbWVQ0afXy0PfrZGL0as_8Jfsfi5Q">