https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93808
--- Comment #18 from Oleg Endo <olegendo at gcc dot gnu.org> --- (In reply to Andrew Pinski from comment #17) > In the original code we have: > if ((uintptr_t)p % 4) { > int l = 4 - (uintptr_t)p % 4; > p += l; > switch (l) { > > l range should be 0...3 Ha! This code is an autostereogram. You gotta stare at it until something comes out of it (or falls in) ... if (0 || e - p >= 4) { if ((uintptr_t)p % 4) { // when here, p % 4 is never zero. // thus, l = 4 - {3|2|1} int l = 4 - (uintptr_t)p % 4; However, that's not where it crashes. It's in the second switch statement. I assume that's because it's never supposed to get there, but it does. What the code does is trying to walk an array of bytes in 4-byte steps. For that it potentially steps 0...3 bytes to get a 4-byte aligned pointer 'p', then does the 4-byte steps in the for loop, then does the remaining 0...3 bytes after the loop. Perhaps this line p = (const char *)s; somehow results in wrong code with p not being updated correctly, and then (e - p) is not in the range {3|2|1|0} as the code expects.