<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=http://email.email.llvm.org/c/eJylVU2P2jAQ_TXhMmoENinLIQfYVT8kttpD1fbqJANx69hZ2wF2f33HTgIsRe2hyCRx_Pzmeb5SmOolv1dC7xL2YbP59ghbIZUDb6DCvbS-E0q-Ihxq1CDKEp2TegcCdsoUQsFeWCkKhSl8raUDV5tOVVAgtIaQtACELxF8jScs1MIRwy9tDhr8SxtWhYdSaG182FvWpAerFB6llg1ZwaNoWoUJXyXTh2Q6Xt9PhxGnztuu9PADksW6fwMwnACk9rA1JmF3CVtCabTzAQYWfWc1zFnC1_TiYdwX8IWwA_4CeSJ5syE88MEoHj0S8AccT6-i9TPXaIQ8TgOe0G6NbRw5QCk4SF9DGQPCR6uOBPYLu7Icdw-CjulJ58nelYEvxg8u9iFGMQyk6Jo7GqU960srPcXJ1uXxz0e_FY2erbWm6ihpzpF7i9qObGTqX7-EcUjm03HLILD_NWb_HO7HuJhZ2QYIu4cwEcc_wKonnB8HDFbyLeZn0z73mNVASSwUvr-J-7r6vLlfbTY3T_qZEnysjRgGohWxYKgIipfo8-iIm7uvZFO-Drqvz0aRuknQXx-wCalvhZdGA43SNK1UaKnCWmUs2hCJ2vs2RizGfmeqwiifGhtaxCv9-VN2_Mg_Pn2_pD4nWR_5yqCDtk_tWP0X7aQ3H1tKWLlqJUObAfKRbBqKjPCoXqiUYz9J4ZM54J4kS2pIemwNoOSvwbGHWpY1bKV1IcefO2lJidSKegnp0uZPJbVoW9QBFPXENmhaL5sR0MoWaT-mkyrn1ZIvxUR0vjY2fxT-FdeTzqr8ym1UUl2RkoNpotR-vL2jkviJpaepdK6j0mAfMp4tZ5M6rzjPxIKVi6rItgUT2_mMnqv3s1nJURR3EyUKVC5PsnXCWCTlq0uhRMaS7GHy_2JkzqaMxnQ-u8sWjKfiblFtGV9ixWczli2oErGhT0UaeEJyTGweKYtu52hRSefdeVHQ12CnEaN2UuilV5h_uREMSpjrjJhEcXlU9hsDfQPB>53591</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
No devirtualization for global variable
</td>
</tr>
<tr>
<th>Labels</th>
<td>
llvm:optimizations
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
MatzeB
</td>
</tr>
</table>
<pre>
Clang/LLVM fails to devirtualize when accessing a global variable. This should be possible since the variable has a known type that cannot be changed. Minimal example:
```
struct X {
virtual int foo() const { return 42; }
int bar() { return foo(); }
};
extern X x;
int f() {
// Performs call with clang; returns 42 with gcc
return x.bar();
// Note that this variant returns 42 with clang + gcc
//return x.foo();
}
```
clang produces:
```
f(): # @f()
movq x(%rip), %rax
movl $x, %edi
jmpq *(%rax) # TAILCALL
```
It could be this (as shown by gcc):
```
movl $42, %eax
ret
```
Demonstration on compiler explorer: https://godbolt.org/z/3P5xG3GPW
Note that clang does perform the devirtualization when the global variable access is immediately visible. However in an example like this which first requires inlining no devirtualization happens in the LLVM optimization pipeline.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyFVU1z2jAQ_TXmslMPkXCAgw-QTD9mSCeHTturbC9YrSw5kgwkv74r2QZCmdYjDLbevn27q10KU73mD0roXcI-bjbfn2ArpHLgDVS4l9Z3Qsk3hEONGkRZonNS70DATplCKNgLK0WhMIVvtXTgatOpCgqE1hCSNoDwJYKv8YSFWjhi-K3NQYN_bcOu8FAKrY0PtmVNerBK4Ulq2ZAXPIqmVZjwVTJ9TKbj_X46rPjovO1KDz8hma_7NwBDBCC1h60xCVskbAml0c4HGFj0ndUwYwlf04vH0S7gC2EH_AXyRPLOIPzgg1M8eiTgTzieXkXvZ67RCWWcFjyj3RrbOEqAUnCQvoYyFoSPXh0J7Dd2ZTlaD4KO6Unnyd-Vg6_GDyn2oUaxDKTomjs6JZv1pZee4uTrMvxz6Leq0bO11lQdHZpz5d6jtiMbufrflTAOyWw6mgwC-6sx-5fwfYybmZVtgLAHCA_i-BdY9YSz44DBSr7H_Gralx6zGiiJhcr3L3HfVl82D6vN5makX-iAj70Ry0C0IjYMNUHxGnMeE3HT-ko2nddB93VsVKmbBP39EZtw9K3w0migVZqmlQotdVirjEUbKlF738aKxdrvTFUY5VNjw4h4ow9_zo6f-KfnH5fU50PWV74y6KDtj3bs_otx0ruPIyXsXI2SYcwA5Ug2DVVGeFSv1MpxnqTw2RxwT5IlDSQ9jgZQ8veQ2EMtyxq20rpwxl86aUmJ1IpmCenS5m8ltWhb1AEU9cQxaFovmxHQyhbJHtNJlfNqyZdi4qVXmH-9wUYRX4c06azKr9JKLdcVKRWAHpTaj18fqGV-YenpUTrXUeuwjxnPlneTOi_mdE23_J4ksGLJ2Iyz2fKeL-YZ394vZhMlClQuT7J1wlgk5avLQIiMJdnjROZsymhNZ3eLbM54Khbzasv4Eit-d8eyOfUZNvRHkAaSUPqJzaO6ots52lTSeXfeFDTrdxoxeiZ-0fna2PxJ-DdcT2IceQziD-vx7FQ">