https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113045
Richard Earnshaw <rearnsha at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |rearnsha at gcc dot gnu.org --- Comment #20 from Richard Earnshaw <rearnsha at gcc dot gnu.org> --- (In reply to Andrew Pinski from comment #9) > This is almost definitely a valgrind issue. > We start with: > /* Align the source pointer. */ > misalign = (uintptr_t)s & 15; > p = (const uint8_t *)((uintptr_t)s & -16); > data = vld1q_u8 (p); > > > Which all other targets do too. > > Basically this is how you realign the pointer and if don't depend on the > bytes that is not in the original pointer, then this is valid. > > Does it work correctly without valgrind? Yes, for the first fetch, we align down to a 16-byte boundary and fetch the full 16 bytes. We then mask off the bytes that are before the real start of the buffer so that they cannot affect the result. So the code is safe, but valgrind has no real way of knowing this. Tricks like this wouldn't work with capability pointers, but we're not concerned about that here; even MTE (on aarch64) would be ok because the alignment used matches the tag granule size. So I'm pretty sure this is a false positive. But perhaps we should just disable the vectorized scanning when valgrind checking is enabled. Note that glibc implementations of str* functions can perform a similar trick, but perhaps valgrind has special knowledge of such cases.