Devotd Github
NewKorean tech

bab2min/kiwi — Fixing the undefined shift behavior of the SIMD search bitmask

bab2min/kiwi changed the bitmask computation of the SIMD search (findAll), removing the undefined shift behavior that occurred when the size was the full width of size_t.

Repositorybab2min/kiwi ↗

bab2min/kiwi changed the bitmask computation of the SIMD search (findAll), removing the undefined shift behavior that occurred when the size was the full width of size_t.

GitHub description: Kiwi(지능형 한국어 형태소 분석기)

stars
★ 796
Forks
81
Language
C++
License
Apache-2.0
Latest release
v0.24.0
Read original source ↗View on GitHub ↗

The latest commit of bab2min/kiwi is a change that fixes the code computing the bitmask for the SIMD search. PR #295 (submitted by ollipa), merged on October 24, 2026, replaced the code that shifted by the full width of `size_t` when `findAll` created a mask keeping only the lower bits of the result with a `lowBitsMask` helper.

kiwi (an intelligent Korean morphological analyzer) is a library that divides Korean sentences into morphological units and assigns parts of speech. `findAll`, the search code, is a function that returns the positions matching a given character in an array of candidate path bytes as a bitmask, and its implementation is split by architecture, such as SSE2, AVX2, AVX512, and NEON. Each implementation appended a mask of the form `((size_t)1 << size) - 1` so as to keep only the lower bits corresponding to the number of bytes compared, but when `size` became equal to the full bit width of `size_t`, such as 64, the shift width equaled the type width, which is undefined behavior according to the C++ standard. The new helper returns a value with all bits set to 1 when `size` is greater than or equal to `sizeof(size_t) * 8`, and the same value as before when it is smaller.

The commit stats are 50 insertions and 11 deletions, and the code was applied uniformly to all of the SSE, AVX2, AVX512, and NEON paths within the single file `src/search.cpp`. Regression tests came along as well. The new file `test/test_search.cpp` checks on the SSE2 and NEON paths that `findAll` returns a value with all bits turned on when all 64 bytes match, and a case was added to `test/test_cpp.cpp` verifying that, with the conglobal model, an input that fills up to 64 path buckets yields 12 morphemes and that "데우" is judged to be a verb (vv). The new test was also registered in two build configuration files. However, what this change addresses is only the bitmask computation of the found paths, and there is no material presenting numerical differences in execution time or accuracy. Whether it improves performance cannot be judged from this material alone; it is closer to a small change that prevents one boundary-condition bug.