<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/90119>90119</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            LLVM does not eliminate or hoist redundant bounds checks for std::vector and std::string
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            missed-optimization,
            hardening
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          ldionne
      </td>
    </tr>
</table>

<pre>
    Given the following code:

```c++
#include <vector>
#include <span>
#include <string>

template <class T>
void use(T const&);

template <class Container>
void f(Container container) {
  for (int i = 0; i != container.size(); ++i) {
 use(container[i]);
  }
}

template void f(std::string);
template void f(std::vector<int>);
template void f(std::span<int>);
```


Godbolt: https://godbolt.org/z/x8fdv8s63

When we compile with hardening enabled, there is a bounds check inside `operator[]`. That check is basically equivalent to `index < size()`. However, it doesn't get elided even though the loop condition should guarantee that the condition always holds. It seems to be elided when iterating over a `span`, but not a `string` or a `vector`, which makes me think the optimizer could be improved.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyMVNFuqzgQ_RrzMmpkTCDkgYcm2dxd6e5btfts8CTM1thZPJDbfv3KQNOmultdCTnEPnN8ZuYMOgQ6O8RK5DuRHxI9cOv7yhryzmFSe_NSfaMRHXCLcPLW-iu5MzTeoMgehTwI-bYWcn4aoXbxmXdVRq6xg0EQ2X7Ehn0vst9-dhgu2v3fEffkzu-H08rYXazmCdBYHQI83RCjJwNDQKHKJ2i8CyxUIdRWZLuvKfbesSaH_T3VSajydhQJF5DagtgslAAn34NQJTkGApEdQIpsF19VGv_dwlaBXqO0WRDM9aJ7sln8-035jkR--JgCgNgclmxuL_dp3bQHNrFd2eNSyQ80X4Df2rUnx7EevxY19_EnMTeH3NlmWr95U3vLInuElvkSIpM6CnU8zwcr35-FOr4KdfxRnsxYhiL7GP93iw6uCI3vLmQRrsQttLo36KJd0enaohFqH33cI1AADbUfnAnQtNg8A7lA0WyF9Bfsdcx7GglRyBU8tZrfcAFqHajR1r4A_jvQqC06BvYxlpzBH9FN8KHFkeF3f8UxGmYPxGA8BifUhuGMDGjJoAGcx8wP53aaNuv9JXrGEJN3EFo_WAPnQffaMSJwFBWB7xhtr_olQOutCSv4gyEgdiFqq_HtmmssFXHMMZbGj9iDjtqnvhUySqwHBud52Z8tU0jwC3LxxYy9ttS00OlnDNBFVeSeJ1n-wtTR6zQvUXmNQN2l9yOaVWKqzGyzrU6wSjfpWm5KladJW2Upqhw3hSpVWmantM50WaRZtinSVOZFmlClpFrLtcqVzGWeruQ2NwblNj2diuZUarGW2GmyK2vHLvomoRAGrLYyTbeJ1TXaMH3ulOooBDQPi1AdSyiUEmovlLqZJ-7kh6SvIt9DPZyDWEtLgcP7DUxssfr-_a8_p9ZOtUNLHbk4Ir6H1lNg6NEMzmjHd9YL03fj09CBdgY-TW0y9Lb6NB7E7VCvGt8JdYxylp-HS-__wYaFOk7ZB6GOUwH-CwAA__8Qati1">