<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/124225>124225</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
clang doesn't perform case lifting
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
ryani
</td>
</tr>
</table>
<pre>
Both gcc and msvc perform this optimization.
Compiler explorer link: https://godbolt.org/z/nxv9bTohe
```
#include <utility>
struct N
{
int val;
N* left;
N* right;
};
enum class D
{
here, pleft, left, pright, right
};
template <typename F> N* search( N* root, F&& dir )
{
N* cur = root;
N* best = nullptr;
while( cur != nullptr ) {
switch( std::forward<F>(dir)(cur->val) )
{
case D::here:
return cur;
case D::pleft:
best = cur;
[[fallthrough]];
case D::left:
cur = cur->left;
break;
case D::pright:
best = cur;
[[fallthrough]];
case D::right:
cur = cur->right;
break;
default:
std::unreachable();
}
}
return best;
}
N* find( N* root, int n )
{
return search( root, [n]( int val ) {
if ( n < val )
return D::left;
else if( n == val )
return D::here;
else
return D::right;
});
}
```
clang correctly determines that the lambda in `find` can only return 0, 2, or 4, and uses that to eliminate the pleft and pright cases from the switch, as well as realizing that nothing can mutate `best` and therefore if the loop exits normally that the result must be NULL. But it doesn't take the next step and realize that the codepath from the `n < val` branch can only go to the `D::left` case, and so on.
In the compiler explorer link I have a manually fused version, and a version where I've manually performed inlining and the case lifting optimization. Both of these clang does a fine job with (although gcc generates slightly better code).
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJyMVtGO2joTfhpzMyoKDoTlIhcsFKlS1av_fwAnmRC3jh3ZE1j69EfjJAR2tz0nQjh2xt9883nGtgpBny1iLjavYnNcqJ4a53N_U1YvClfd8ldHDZzLEpStoA2XEjr0tfMtUKMDuI50q38r0s4uRbIXyf7g2k4b9IBvnXEePRhtf4l0Dw1RF0S6F_Ik5OnsqsIZWjp_FvL0W8iTfbvsiv-5BgcgkSXjL9kLmWpbmr5CEOmhJ2003UT6dbAM5PuS4Af3tq8i2YO2BBdlRBp7APBDyD0YrOndkNfnZhwT2-P4kuzR9i2URoUAxxkVABr0KOQBuoglDzC13YAkDyPkMx5h2xlFkT3dOrSqRTiJ9OvAIqDyZSPky0jKuYh0EjITMoNKexBy90QkGpa9B5EehwnPgRUYKH6zvTEd-TsVtrg22iC7iwBy9WDHjmB2w0-4ahrYBap4_dJ97fxV-UqkBw5CyJdKe2YoX8refxHpVxafgSLrCWiELVVAOA5AUc90_2A0PR6p95YZzpFNzyPCsBKfQtw1-BQkMuK8f62VMdR4158bsTnyL_1A9M9epkUYI39IssKj-vUv7McE_I_0_873Dz7-4uId94dq-EDm81gqrFVvJvR7fvTWoyobVcQ04yx4msmlMfSGt7EzLjnHPZdk_BpTuta2-lAjXOn2Q3WMSHNdTeZi82pZMPky7RGfJLyugQ0sV-tk8i7u0cFTcjxCoAkIup5gjizyA9Lz9KEI3k__q8fHlWKVJoVHxR63zmRfGmXPUDrvsSRzgwoJfastBqBGEVCDYFRbVAq0BZElUeksgVJZcNbcJucJSyj5z3lYc8vHQh_uQA7Q6FZb3uoYNRZnNBoSPeZlgNq7Nn6ftpYDqABXNIZbj8ro39qeB1DrqOEOk2l7irtolsQkyZKITSxg7TwrPgTjXAf4pimAdb5VxtzmSD2G3hC0fSAoEH78__v3JcBrT6AJKofBCrklIPVriMHiG0Eg7KKvgRzOcKWrsFPUzEGJLLmnDlMsvLJlM4t5dizUaPmYQVHxgJOuwcH9VP1mR2efHa7wDRp1QVDQKtvHaOs-YAUX9EE7OwGqaQCurBh8E3J7wXnSeLRjBdoabVn0Ud5hPzG6Jh58OvUB4h3BReUDwpBsrCMoLlmEn66Aq6aGi0oZanjfineKM1r0ijBAMJwd5gYFEqGPogq5Wy6qPK126U4tMF9t0222k4nMFk1eV0mRYb3Ldtkqq5PdKklfdnJVq7IqXhCzhc5lIjfJSq6T9SpdZ0tZZpvNqi7TclvJdKvEOsFWabM05tLyLWShQ-gxX8m1lJuFUQWaEC9GUsaYhJR8R_I5T_hS9Ocg1onRgcIMQZoM5rMEQypNV6ZHERe9N_m7G5Gmpi-WpWuFPDHk2HzpvPuJJQl5ihSDkKeR5SWX_wQAAP__Dnffsg">