https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119016
Tamar Christina <tnfchris at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P3 |P1 Last reconfirmed| |2025-02-26 Status|UNCONFIRMED |NEW Ever confirmed|0 |1 --- Comment #5 from Tamar Christina <tnfchris at gcc dot gnu.org> --- Confirmed. Slightly easier to digest case: --- #include <stddef.h> #include <stdint.h> __attribute__((noipa)) char *svn_eol__find_eol_start(char *buf, size_t len) { for (; len > sizeof(uintptr_t); buf += sizeof(uintptr_t), len -= sizeof(uintptr_t)) { uintptr_t chunk = *(const uintptr_t *)buf; uintptr_t r_test = chunk ^ 0x0a0a0a0a0a0a0a0a; uintptr_t n_test = chunk ^ 0x0d0d0d0d0d0d0d0d; r_test |= (r_test & 0x7f7f7f7f7f7f7f7f) + 0x7f7f7f7f7f7f7f7f; n_test |= (n_test & 0x7f7f7f7f7f7f7f7f) + 0x7f7f7f7f7f7f7f7f; if ((r_test & n_test & 0x8080808080808080) != 0x8080808080808080) break; } #pragma GCC novector for (; len > 0; ++buf, --len) { if (*buf == '\n' || *buf == '\r') return buf; } return ((void *)0); } int main() { char p[] = { 0x2f, 0x2a, 0xa, 0x20, 0x20, 0x20, 0x62, 0x75, 0x67, 0x33, 0x33, 0x37, 0x39, 0x37, 0x32, 0x33, 0x2e, 0x63, 0xa, 0x2a, 0x2f, 0xa, 0xa, 0x23, 0x69, 0x6e, 0x63, }; size_t len; char *end = p + (sizeof(p) / sizeof(p[0])); int i = 0; do { char *start = p + len; const char *eol = svn_eol__find_eol_start(start, end - start); len += (eol ? eol : end) - start; i++; } while (((end - p) > len + 2) && i < 100); }#include <stddef.h> #include <stdint.h> __attribute__((noipa)) char *svn_eol__find_eol_start(char *buf, size_t len) { for (; len > sizeof(uintptr_t); buf += sizeof(uintptr_t), len -= sizeof(uintptr_t)) { uintptr_t chunk = *(const uintptr_t *)buf; uintptr_t r_test = chunk ^ 0x0a0a0a0a0a0a0a0a; uintptr_t n_test = chunk ^ 0x0d0d0d0d0d0d0d0d; r_test |= (r_test & 0x7f7f7f7f7f7f7f7f) + 0x7f7f7f7f7f7f7f7f; n_test |= (n_test & 0x7f7f7f7f7f7f7f7f) + 0x7f7f7f7f7f7f7f7f; if ((r_test & n_test & 0x8080808080808080) != 0x8080808080808080) break; } #pragma GCC novector for (; len > 0; ++buf, --len) { if (*buf == '\n' || *buf == '\r') return buf; } return ((void *)0); } int main() { char p[] = { 0x2f, 0x2a, 0xa, 0x20, 0x20, 0x20, 0x62, 0x75, 0x67, 0x33, 0x33, 0x37, 0x39, 0x37, 0x32, 0x33, 0x2e, 0x63, 0xa, 0x2a, 0x2f, 0xa, 0xa, 0x23, 0x69, 0x6e, 0x63, }; size_t len; char *end = p + (sizeof(p) / sizeof(p[0])); int i = 0; do { char *start = p + len; const char *eol = svn_eol__find_eol_start(start, end - start); len += (eol ? eol : end) - start; i++; } while (((end - p) > len + 2) && i < 100); } --- The code is peeled but the address ends up being not aligned: Program received signal SIGSEGV, Segmentation fault. 0x000000000040135f in svn_eol__find_eol_start (buf=<optimized out>, buf@entry=0x7fffffffe2f2 "\n bug3379723.c\n*/\n\n#inc\027", len=<optimized out>, len@entry=25) at oel.c:8 8 uintptr_t chunk = *(const uintptr_t *)buf; (gdb) display/i $pc 1: x/i $pc => 0x40135f <svn_eol__find_eol_start+351>: movdqa (%rdi,%rsi,1),%xmm10 (gdb) p/x $rdi+$rsi $1 = 0x7fffffffe2f2 which is not 16-bytes aligned, hence the alignment fault.