<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/72590>72590</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Improvement for relative load on x86
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
PiJoules
</td>
</tr>
</table>
<pre>
LLVM will compile the following IR:
```
declare void @extern_func()
define void @foo(ptr noundef %a) local_unnamed_addr {
entry:
%vtable = load ptr, ptr %a
%func_ptr = tail call ptr @llvm.load.relative.i32(ptr %vtable, i32 0)
tail call void %func_ptr(ptr %a)
tail call void @extern_func()
ret void
}
declare ptr @llvm.load.relative.i32(ptr, i32)
```
into this
```
foo:
pushq %rax
movq (%rdi), %rax
movslq (%rax), %rcx
addq %rax, %rcx
callq *%rcx
popq %rax
jmp extern_func@PLT # TAILCALL
```
These instructions
```
addq %rax, %rcx
callq *%rcx
```
can be simplified into
```
call *(%rax,%rcx)`
```
which saves 2 bytes per relative call. This particular pattern is seen for every virtual call with the relative vtables ABI for x86, so we can save roughly 2 bytes per callsite if we can teach llvm to lower to these instructions.
Note this isn't specific to the `llvm.load.relative` intrinsic. This intrinsic gets lowered to a `load + GEP`:
```
define void @foo(ptr noundef %a) local_unnamed_addr {
entry:
%vtable = load ptr, ptr %a, align 8
%0 = getelementptr i8, ptr %vtable, i32 0
%1 = load i32, ptr %0, align 4
%2 = getelementptr i8, ptr %vtable, i32 %1
tail call void %2(ptr %a)
tail call void @extern_func()
ret void
}
```
but this still produces the same asm.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEVlFvqzgT_TXOy-hGYEpIHnhI26-fusquqlW1r5XBQ5grY3Ntk7T_fmVDQ1IlV7vSlRZFIMKZM8dnPAPCOdprxJLl9yx_XIjBt8aWL_SbGRS6RWXkR7nb_fU7HEkpqE3Xk0LwLUJjlDJH0nt4_pNlW5Y8suTzvEqmX7yVWCthEQ6GJLC7BN89Wv3WDLpmfM345jxWYkN6xjbGML7uvQVtBi2xAcZzwfgGlKmFehu0Fh3KNyGlBVbcjySovf04iYIQc_CiUggsewRlhITeW8YfwmVknJFB11v4P4K9IAW1UGqE3iVKHbploFhaVMLTAZeU8UnkKVHgpoxDcloenFGNq5tTzdHiJ_ibzgFY9BE0OVk8Xlo6-v8PFjDJnmtyWcnxTNob8C25q5hQsWwLk7J-cO0PiL5a8f4pdzw6cwiPIC4lt5JCWv5wC-vUj0-oeD-D1l-gQsqJdgReRwVfR2Hbi8e96c-jL2K-d328npfhLnnZvcLXg_EMXrfPu4ftbvcTJ19bdAiknbdD7cno65b-kpV94ayFhgrBUdcragglhLLegCo1sp3Mf5iY-WZe0WXQsaW6BScO6IBD9eHRQY8WPvdclLmE15Yc9MJ6qgclLPTCB2-BHDhEDY2xgAe0H3Ag6wcxNcSRfBun0IlubDsH2_vnGPS-XgWDnIFjyKWjFLBm2Lfq40JRIHTkEaj5xHoUdQuhUcAbUOaIFuKe_1qu5Xk1_zAeY18AOc144cH1WFND9RQMbHWl-9gqCd5b0o7qyZHTPezRu1EBykAjIkmYYIzfw___9xIcz24N3v9mlvIHEIr2GtZnQUnE79Gjwg61D2han8V9HZxzaDqnisPpFJLMqe7O8PzfpQoZbs9ofnU4_4LZfFmravDj3nE-vGl7a-RQo4vbxokOQbhuuZBlJjfZRiywTIskSddZnvJFW6ZpkVVVkosmx0I262KVFZJvci6wSIoiWVDJE56laVokaZrmfJkmucyLbJUWeb1umnVYQSdILeMGNXa_IOcGLAueb5KFEhUqF78SONd4hPiQcR4-GmwZYr5Vw96F1ws572YWT15h-dz11hxiMWJ3nto2FtXo0K6Lwaqy9b53YbfxJ8af9uTboVrWpmP8KVBOl2-9Nd-x9ow_RSGO8aco9O8AAAD__yJNlmg">