Skip to content

Commit 191b167

Browse files
committed
fix(bb): unaligned SIMD store in Constantine x4 recoder (debug segfault)
1 parent 64f5310 commit 191b167

1 file changed

Lines changed: 7 additions & 3 deletions

File tree

barretenberg/cpp/src/barretenberg/ecc/scalar_multiplication/pippenger_constantine.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,14 +214,18 @@ struct ConstantineSliceParamsU32 {
214214
// On WASM the explicit `wasm_v128_store` is used because earlier codegen for
215215
// the equivalent struct-wrapper assignment was observed to round-trip the
216216
// vector through 4 scalar memory slots; the intrinsic guarantees the
217-
// `i32x4.store` opcode. On native the `vector_size` store lowers directly to
218-
// SSE2 `movdqu` / NEON `st1`.
217+
// `i32x4.store` opcode. On native we go through `memcpy`: `dst` is only
218+
// guaranteed `uint32_t`-aligned (4 bytes), but `SimdU32x4` has 16-byte natural
219+
// alignment, so `*reinterpret_cast<SimdU32x4*>(dst) = v` emits an *aligned*
220+
// store (`movdqa` / `vst1.128 [align:128]`) and faults on a 4-byte-aligned
221+
// destination. `memcpy` lowers to the intended single unaligned store
222+
// (SSE2 `movups` / NEON `st1`) without assuming 16-byte alignment.
219223
[[gnu::always_inline]] inline void simd_u32x4_store(uint32_t* dst, SimdU32x4 v) noexcept
220224
{
221225
#ifdef __wasm_simd128__
222226
wasm_v128_store(dst, reinterpret_cast<v128_t>(v));
223227
#else
224-
*reinterpret_cast<SimdU32x4*>(dst) = v;
228+
__builtin_memcpy(dst, &v, sizeof(v));
225229
#endif
226230
}
227231

0 commit comments

Comments
 (0)