Fix alignment UB in distance_hamming_u64

Casting unaligned blob pointers to u64* is undefined behavior on
strict-alignment architectures. Use memcpy to safely load u64 values
from potentially unaligned memory (compilers optimize this to native
loads on architectures that support unaligned access).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Garcia 2026-03-31 14:57:01 -07:00
parent 7de925be70
commit 2f4c2e4bdb

View file

@ -734,10 +734,13 @@ static unsigned int __builtin_popcountl(unsigned int x) {
#endif #endif
#endif #endif
static f32 distance_hamming_u64(u64 *a, u64 *b, size_t n) { static f32 distance_hamming_u64(const u8 *a, const u8 *b, size_t n) {
int same = 0; int same = 0;
for (unsigned long i = 0; i < n; i++) { for (unsigned long i = 0; i < n; i++) {
same += __builtin_popcountl(a[i] ^ b[i]); u64 va, vb;
memcpy(&va, a + i * sizeof(u64), sizeof(u64));
memcpy(&vb, b + i * sizeof(u64), sizeof(u64));
same += __builtin_popcountl(va ^ vb);
} }
return (f32)same; return (f32)same;
} }
@ -761,7 +764,7 @@ static f32 distance_hamming(const void *a, const void *b, const void *d) {
#endif #endif
if ((dimensions % 64) == 0) { if ((dimensions % 64) == 0) {
return distance_hamming_u64((u64 *)a, (u64 *)b, n_bytes / sizeof(u64)); return distance_hamming_u64((const u8 *)a, (const u8 *)b, n_bytes / sizeof(u64));
} }
return distance_hamming_u8((u8 *)a, (u8 *)b, n_bytes); return distance_hamming_u8((u8 *)a, (u8 *)b, n_bytes);
} }