<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/141542>141542</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[CodeGen] Poor code size for switch-based tail call dispatch
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
resistor
</td>
</tr>
</table>
<pre>
In a reduced example involving use of a switch statement to dispatch to a set of tail calls, LLVM inserts identical frame teardown code into every case of the switch statement. Since all of the cases here are nothing but tail calls, the teardown could and should be done in the switch teardown block instead. This happens at all optimization levels, including -Oz, though the details differ a bit. It appears to impact at least RISC-V and AArch64, and at a glance it appears to impact X86-64 as well.
Godbolt example demonstrating the issue on RISCV32 and AArch64: https://godbolt.org/z/sdWreMGxn
Source code, reduced from a real example:
```
struct bar {};
struct foo {
unsigned char a;
bar *b;
};
int f1(foo*, bar*);
int f2(foo*, bar*);
int f3(foo*, bar*);
int f4(foo*, bar*);
int f5(foo*, bar*);
int f6(foo*, bar*);
bar* unseal(bar*);
int func(foo *f) {
bar* b = unseal(f->b);
switch (f->a) {
case 0:
return f1(f, b);
case 1:
return f2(f, b);
case 2:
return f3(f, b);
case 3:
return f4(f, b);
case 4:
return f5(f, b);
case 5:
return f6(f, b);
default:
return -1;
}
}
```
Snippet from RISCV32 showing redundant frame teardown:
```
...
.L5:
ld s0,0(sp)
ld ra,8(sp)
addi sp,sp,16
tail _Z2f5P3fooP3bar
.L3:
ld s0,0(sp)
ld ra,8(sp)
addi sp,sp,16
tail _Z2f6P3fooP3bar
.L9:
ld s0,0(sp)
ld ra,8(sp)
addi sp,sp,16
tail _Z2f1P3fooP3bar
...
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy8VsFu4zYQ_Rr6MrAhU5JtHXxQnHqxwC4aNEVa9FKMxJHFliYFknJ28_XFSLYTu0ndXhoElkS-ee9xyCGJIeidJVqL_E7k9xPsY-v82lPQITo_qZz6vv5sAcGT6mtSQN9w3xkCbQ_OHLTdQR8IXAMI4VnHuoUQMdKebIToQOnQIbdGxwiKDI2oDdRoTBByA1--PH0FbQP5GEArslHXaKDxuCeIhF65Zwu1UywaHdCB_HeocZSNLf1NeAaP2tYEaMwJwvAALXkC9ATWxZa9V328csPgN6K9UYBWQWiH14pAOctG3gqf8ZVx9Z88lkioZvBzqwO02HVkA2Ac_XRR7_ULRu0sGDrQKKttbXrFlqY_vow-XL9rBxVFbDGA0k1DHhAqHWfwOQIzow-cW73vsI4sYghDhJ8-P26mT4P1svR1u8iYlD_ZB-wMcoL0exy_rhbTRQYY4JmMmYmkFEn5yanKmXiefkV7Z0P0GNkzu9Qh9ATODtJPqbzQTktoY-yCSEsht0JudyPfzPmdkNsXIbdB_eLp66dvdhR8dL2vaZh2dn5afo13-2E1ojl5YXKOWSTH_6QM0fd1hAo9iOWdWN6L9O61uXFuaE5KAIDeDiWgoG7RA45I7hiiZVmNLWcSkZTaRmjmQq4a54Qs2V-FfngrRtCAkDcR6U1EdhOR30Qs_gkxfnIWCI2Qq6vuE0dv65GFU9IIWbzJ4JGiApHevxI1U5H-UJ2JGHgsl1MnXtLw31DVCa-S1zYAT7H39pjyYQwXtOfA-THwhJc38PIjofSdwCEi_SgiuyGVfRSY3wjMPwpcfByoqMHexMtsTOcivQOAI47X87iqL0uHS8_qrqM41tqpmkPrnrnUuRCtQl4TFxv0KHZFNpvx9jH7cjUIo8ZnSITcJEKuQsdjuAB4FHKzeqcPldJDcCfkZviZL950D7s5APz-m2zyh7Rx7iHlBco2TrP3b_THXP9XE2_VF1fqxf-cBPYwv_QwTMd5giZqnaoiLXBC6_kyW6XzVZEVk3adpWmKlOXzpkrrapUpKopcSiyyol7WcznRa5nIPMnlMsmSIilmebWkqm5WVZYmy6KoRJbQHrWZGXPY8yY_GY6H9Tyb55mcGKzIhOHSIaWl5_HwEFLyHcSvOWha9bsgssToEMMrTdTRDLeVjVP0iazI7-HBOT_eD4J-IWicP-400woDqdcD_nwbmfTerK8OJB3bvprVbi_kluWOj2nn3R9URyG3g8kg5PY4isNa_hUAAP__JJCuLA">