Skip to content

Fix use-of-uninitialized-value in SVE accumulator operations#331

Merged
ashvardanian merged 1 commit intoashvardanian:main-devfrom
ClickHouse:fix-sve-msan-uninitialized
Mar 31, 2026
Merged

Fix use-of-uninitialized-value in SVE accumulator operations#331
ashvardanian merged 1 commit intoashvardanian:main-devfrom
ClickHouse:fix-sve-msan-uninitialized

Conversation

@alexey-milovidov
Copy link
Copy Markdown
Contributor

Summary

Use _m (merge) instead of _x (don't-care) for SVE multiply-accumulate operations (svmla, svmls) on accumulator vectors in spatial.h and dot.h.

The _x variant leaves inactive lanes undefined when the predicate is false (i.e., for elements past the end of the input array). However, the final horizontal reduction svaddv uses svptrue (all lanes active), which sums all lanes — including those with undefined values from _x. This causes MemorySanitizer to report use-of-uninitialized-value when the input vector length is not a multiple of the SVE register width.

The _m (merge) variant preserves the first operand (the accumulator) for inactive lanes, keeping them at their initialized zero value. This is correct because:

  • Accumulators start at 0
  • Active lanes accumulate normally
  • Inactive lanes retain 0 (or their previous accumulated value)
  • The final svaddv(svptrue, ...) correctly sums all lanes

Affected functions

spatial.h: simsimd_l2sq_f32_sve, simsimd_cos_f32_sve, simsimd_l2sq_f64_sve, simsimd_cos_f64_sve, simsimd_l2sq_f16_sve, simsimd_cos_f16_sve, simsimd_l2sq_bf16_sve

dot.h: simsimd_dot_f32_sve, simsimd_dot_f32c_sve, simsimd_vdot_f32c_sve, simsimd_dot_f64_sve, simsimd_dot_f64c_sve, simsimd_vdot_f64c_sve, simsimd_dot_f16_sve, simsimd_dot_f16c_sve, simsimd_vdot_f16c_sve

Reproduction

Detected as MemorySanitizer: use-of-uninitialized-value in simsimd_cos_f32_sve during ClickHouse CI stress tests on ARM with MSan.

Use `_m` (merge) instead of `_x` (don't-care) for SVE multiply-accumulate
operations on accumulator vectors. The `_x` variant leaves inactive lanes
undefined, but the final `svaddv` with `svptrue` sums all lanes including
those undefined ones, causing MemorySanitizer to report
use-of-uninitialized-value when vector length is not a multiple of the
SVE register width. The `_m` variant preserves the accumulator value for
inactive lanes, keeping them at their initialized zero.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@alexey-milovidov alexey-milovidov force-pushed the fix-sve-msan-uninitialized branch from e5c7bf0 to fb679cb Compare March 30, 2026 19:07
@ashvardanian ashvardanian changed the base branch from main to main-dev March 31, 2026 14:05
@ashvardanian ashvardanian merged commit ac27cde into ashvardanian:main-dev Mar 31, 2026
73 of 83 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants