<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/85551>85551</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Indexing bounds checks are not hoisted out of a loop
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
davidben
</td>
</tr>
</table>
<pre>
I played around with some variants on using std::span bounds checks, and it seems Clang is not yet very good at hoisting checks out of loops.
Consider a (slightly silly) function like this:
```
int sum_prefix(std::span<const int> s, size_t n) {
int ret = 0;
for (size_t i = 0; i < n; i++) {
ret += s[i];
}
return ret;
}
```
With bounds checks on, `s[i]` will check that `i < s.size()` at every loop iteration. But ideally we'd do a single check that `n <= s.size()` once, before the loop. That then allows Clang to vectorize the loop and do other things.
Here's a godbolt with some more illustrative variations:
https://godbolt.org/z/zYbfzco4e
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJxcVEGv4jgM_jXpxRoUUkLh0MMDFu3cV1rtaZQ2ps1OSFDiwvB-_cjpG3gPVNpE_vzZX2zH5OyGgNgKvRP6UJmJxphaa67OdhiqLtp7-x0u3tzRgklxChZujkbI8YxwNcmZQBligCm7MEAmK-o3Ub_liwnQMT5DP2L_Mwu1BxMsOIKMeM6w9yYM4DKESHBHgiumOwwxWjAEY3SZmHL2hjgRxBP4GC95IeRByLf5vY8hO4sJDAi1yd4NI_k7ZOf9XagtnKbQk4sBvPuJQKPLnOFMsJYfT9m6QJCn849LwpP7xWSf1Yh638eQCVwgUf8FRVB27_iDIHAg0exmHgBgECQkEPUBpKg_WU4xlURnT_dAlOUeQlkKtSvPCyv_CqvasVsWeueEPjz5RXN4ohPSlAJ_HoCH_UX6_P6XK_ulaBADyxRr-Yi1lnBz3s8AoNEQm-fk84JlCbURastAQ4Clqlw2cITJcCkWsJsInEXj_R1uKFRjwUYwwE3k8YU7MHfR-0IfQ4-cXoenmLi2WAIt4B_2pBEDGO_j7U-vUYQr9hSTe3-iS1PaCJFGTNwfYfjaYH9j4gwzGBii7aKnTyNw5sDO-ykTa7t-DAWrfPbZSHQpO3UU6vhBsohpEOr4zv__utN7H1dY2ba223prKmyXzVKulWx0U42t7pY16iV2cr3q5Ba7rle10XV32iy3dd9UrlVSrWS9XCuptG4WK72xK93rXmnTyM1WrCSejfML769njl25nCdsN1rrZeVNhz6Xa0CpgDcoRqEU3wqpZZ9v3TRksZLeZcpPFnLksf0eLP7iaf3aPSZhme4yzGj_DLEpB19NybcvR-NonLpFH89CHTnEx-fbJcX_sSehjiWxLNSxJP47AAD__-uPe4Y">