<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/62894>62894</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[x86] Use function-relative label differences in the large code model, and consider it in other code models
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
rnk
</td>
</tr>
</table>
<pre>
This is the code pattern LLVM currently uses for jump tables:
```c++
int f(int x, int y) {
switch (x) {
case 0: y *= 2;
case 1: y++;
case 2: y *= 3;
case 3: y++;
case 4: y += 4;
}
return y;
}
```
->
```asm
movl %edi, %ecx
leaq .LJTI0_0(%rip), %rdx
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
...
.section .rodata,"a",@progbits
.p2align 2, 0x0
.LJTI0_0:
.long .LBB0_2-.LJTI0_0
.long .LBB0_3-.LJTI0_0
.long .LBB0_4-.LJTI0_0
.long .LBB0_5-.LJTI0_0
.long .LBB0_6-.LJTI0_0
```
As shown, the address of the jump table is materialized (LEA), the offset is loaded, added to the materialized offset, and we jump.
First, these label differences may overflow in the large code model when .rodata is far from .text. This code pattern also requires a static relocation for each entry because the delta is cross-section. See the objdump output:
```
RELOCATION RECORDS FOR [.rodata]:
OFFSET TYPE VALUE
0000000000000000 R_X86_64_PC32 .text+0x0000000000000019
0000000000000004 R_X86_64_PC32 .text+0x000000000000001f
0000000000000008 R_X86_64_PC32 .text+0x0000000000000025
000000000000000c R_X86_64_PC32 .text+0x000000000000002c
0000000000000010 R_X86_64_PC32 .text+0x0000000000000032
```
We could, however, change the code pattern to avoid these relocations by adding in a displacement to the `movslq` instruction above, consider this assembly:
```asm
movl %edi, %ecx
leaq .Lfunc_begin0(%rip), %rdx
movslq .LJTI0_0-.Lfunc_begin0(%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
...
.LJTI0_0:
.long .LBB0_2-.Lfunc_begin0
.long .LBB0_3-.Lfunc_begin0
.long .LBB0_4-.Lfunc_begin0
.long .LBB0_5-.Lfunc_begin0
.long .LBB0_6-.Lfunc_begin0
```
This doesn't add any additional instructions, but it does use a more complex address mode which increases code size by 4 bytes, which could result in runtime performance degradation. Normally, we never care about static object file size, but I imagine that computing smaller, non-negative offsets results in more zero bytes in the jump table that probably compress better in the end.
We can't use the displacement encoding trick in the large code model. Instead, we have to materialize a 64-bit offset and add it, but that's the large code model for you.
@aeubanks @jyknight @tkoeppe
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysV29v4rgT_jTmzQiUOiGFF7ygpUj9qb_tqtvdu3tVOfGEuHXs1Hb4s5_-ZCehQNk9TjqEwGHmGdvjZ54xzFqxUogzMr4h48WANa7UZmbU2yDTfDd7LoUFYcGVCLnmCDVzDo2Ch4cf_4e8MQaVkztoLFootIHXpqrBsUyiJfGcRAsSzUkate-c0Bv_Dr8K5aAgdOK_t4Tegh_sCJ0Cue5cAOxGuLwEQifbY0vOLEJE4jnsgNA5iRdASbzHBfNVMHdzntjoETQ-NcdnocGU9Mgbj0wOkOR60Q8NusYo2O2te9s-Ge3jkMR3JwZmqy5MpdcSAIDQMXLhc-RH-bafpX1JZO_-e_Twv-f76CUidELo2Iia0GmHMfwEU-m1le_QuXKffz_I_SA5wJ3OxTh_71bUos56vVb1e0jtgW00Gh07jSzmTmi1fzaaM8fCSigjlPpREtVGrzLhbAce1ZRJsdqjvBdE2y6b-xT01NsHl1qtQo5ubqIXOtw7dlGPzPGp-WyQ5PdBxhcFSU-8Ttgxt2BLvVF-k74EGecGrQVdhMePYvM1WjGHRjApfiL3J_twN-9O0vvqorDovJ_UjCP3vzPOkYPTweEI3noHH8Vh007VHWD7uRTGui64RZAsQwlcFAUaVDn65exAr9EUUm9AqDCHZGbVCUmlOUrYlKj6k_drK5iBwugKRg63bgRBf46Eh0mrweB7IwxaYGAdcyIHg1LnLPDJyxCyvARUzuwgw5w1FsP8HGU7T260tcOOgSP4hq1dZ6_c51Q3rm7cZwFrH5_uHh5v58_3j1_g6e728WnxDZaPT0DGNz2Hx4s99nG5_Hb3DB-v57--3sGP-cP3ru6jkxc8vfw5SV_S5OXrbUzbRBB6E22P3a6mZ-HJpfDiLHxyIZyOz8LzS-H5OfjVpXuP6dlzaT__8ARrZCB4qTe4RuOHecnUCj83MqeBrbXgHY8_eGQh2_kKEWrl6cuAC1tLlmOFyvVFQ9KolVKSRiCUdaZpRY1leo1hXq2s4GjAeSoza7HK5O4ztT5U_0Oi5cXKXzQqf8lwJdS_kf9ee4bnAvxnTSF0g2A-3xD-QbQ_JPtwjb_R1Pis62fxvjDc-IJw6Tmfs-wMgsY1WkXotfOpA6ZannneMHnIIutzmTUOhAsYf80CBpU2nsRVLXG7bwleT2FTirwEoXKDzN_IAtOt-ImeywlkO4chZusXygQM2kY6T3HTKCcqhBpNoU3FVO4Vc2UYZ61MfvG_SrkLIRCUry3ImUFP98b1WqyzV8wdFEK2k_e7uAdRsZVQvgqZCztonC8v66O2Zaq0GipcMSfWfc-y3RKtX2PY-080ut1M31gOOmGIXRudsUzuwiQhPxn6eu_9UfHRqWiw9kj2veKw3FHlOiiBMyJ_-1U7G8G9sg4Z7xJUsjV6pThorcAgTYaZcH1D9v3Vs0C4Pk1-A4Re2_Md03e3nW6OVk-SiGGTMfVmgSTR6-5NiVXp_Ni9aaxrhAGfxXwaT9kAZ1fpJJlc02h8PShnOEXO04xGCRYZS3Ma0zSdjNPJNEaMczYQMxrROBrTmEZRNE5GrMiTJKNY4KSgU44kibBiQo6kXFcjbVYDYW2Ds5ROpskgXAxs-H9BqcINBKO_3o0XAzPzmGHWrCxJIimssx9RnHAy_DHZTlIyXsB3i-CLzHNxaFC2HPl88fjF4fSXmb0gi0B67UpP4r2bHTRGzkrn6vAHhi4JXa6EK5tslOuK0KVfX_c1rI32VCd0GXZlCV2GXf8dAAD__7yk69c">