Last 12 weeks · 138 commits
5 of 6 standards met
Summary Optimize AArch64 Neon support functions and add Neon accelerated bitSplit floating-point encode/decode paths. This change: adds independent compile-time feature detection for Neon, DotProd, I8MM, SVE, SVE2, and SVE2 BitPerm; replaces the SVE2 BitPerm-based 128-bit mask extraction with native Neon implementations, using I8MM or DotProd when available and a baseline Neon fallback otherwise; adds a native 256-bit Neon SIMD wrapper backed by two 128-bit vectors; adds optimized Neon implementations for bf16, fp16, fp32, and fp64 encoders and decoders; preserves the existing scalar/reference implementations as fallbacks on non-Neon targets; adds negative-value round-trip tests for bf16, fp16, fp32, and fp64 to verify correct sign-bit handling. The optimized paths show substantial speedups on several tested AArch64 CPUs. Type of Change Performance improvement Test Plan Added round-trip coverage for negative bf16, fp16, fp32, and fp64 values to verify that encoding and decoding preserve the sign bit correctly. Validated the optimized encode/decode implementations against the existing reference behaviour. Performance was benchmarked using the enwik5 dataset on multiple AArch64 CPU cores by . The Neon implementations were compared against the reference implementations using both Clang-22 and GCC-16 builds. Decoder benchmarks showed improvements: Encoder performance varies by CPU/compiler combination: Clang-22 emitted essentially the same instructions as the auto-vectorized implementation but scheduled them differently and replaced some of the hinted intrinsics, while GCC-16 generally performed better by preserving those hints and following the intrinsic-defined instruction ordering more closely: Test Configuration Compiler: Clang-22, GCC-16 Build type: Release / benchmark build Platform(s): AArch64
xxhash issue reported upstream FYI What it shows The bug is in src/openzl/shared/xxhash.h: with XXH_FORCE_MEMORY_ACCESS == 1 (the default for GCC), XXH_read32/XXH_read64 read through a __attribute__((__aligned__(1))) typedef. That attribute lowers alignment but grants no __may_alias__, so the access is still a uint32_t/uint64_t lvalue. Reading memory whose effective type is something else (a float/double written through a sibling pointer) is UB under C 6.5p7, and GCC's TBAA is allowed to assume the store doesn't alias the load and hoist the load out of the loop — exactly the "code hoisting in MyMap_insert" you described. Reproduction (gcc-16, -O2 -march=x86-64-v3) XXH_read32 : hoisted(aliased)=0000000000000000 correct(memcpy)=00000010420b0000 MISMATCH (load hoisted) XXH_read64 : hoisted(aliased)=0000000000000000 correct(memcpy)=d041600000000000 MISMATCH (load hoisted) The generated code confirms the hoist: MyMap_insert_u32: movl (%rdi), %eax # load key_slot ONCE, before the loop movl $0x42bd0000,(%rsi) # store final float salq $6, %rax # acc = pre-loop value ITERS ret It reproduces at -O2/-O3, with and without -march=x86-64-v3 — the driver is TBAA + loop-invariant motion, v3 is just your trigger. Files (in xxh_repro/, also as xxh_aliasing_repro.tar.gz) repro.c — verbatim xxHash read helpers (UB form) + memcpy reference + __may_alias__ source-fix variant; four noinline,noclone MyMap_insert_* loops compared. run.sh — builds buggy (-O2 -march=x86-64-v3) and fixed (-fno-strict-aliasing) and prints both. README.md — symptom, root cause, generated code, fixes, toolchain. Fixes (all demonstrated in the reproducer) Source (preferred): add __may_alias__ to the typedefs in XXH_read32/XXH_read64 — the may_alias-fix rows are correct even under strict aliasing. This mirrors what xxHash already does for NEON via XXH_ALIASING. Build flag: -fno-strict-aliasing (works, broader perf cost). Config: set XXH_FORCE_MEMORY_ACCESS=0 (memcpy-based reads, the documented safe path). xxh_aliasing_repro.tar.gz
Summary: D116655191 synced the codec into , and since then any in fbcode stalls indefinitely on . Full analysis is on that diff in the Review Assistant panel; abridged here: Under clang 19 at the translation unit never finishes — I killed it at 10m28s with 2.1 GB RSS still climbing. Three samples of the process all land in SelectionDAG DAGCombine: , and -> -> deeply recursive on . Source bisection pins it to , which complements a (, ) while also round-tripping it through for . A -only variant of the same file compiles in 0.35s. openzl never saw this because pins , where the unmodified file compiles in 0.43s. A build reaches the target through an external dependent under , bypassing the package pin. Deriving the left-child mask with a second comparison instead of complementing keeps LLVM 19 out of that combine loop and costs nothing: is the exact complement of on unsigned lanes, and in the tail . The emitted bitstream is unchanged. Both trees are updated, since mirrors dev into prod byte-for-byte. Reviewed By: kevinjzhang Differential Revision: D117300734
Repository: facebook/openzl. Description: A novel data compression framework Stars: 3164, Forks: 162. Primary language: C. Languages: C (50.4%), C++ (44.2%), Python (1.7%), TypeScript (1.2%), Cuda (1%). Homepage: https://openzl.org Latest release: v0.2.0 (3mo ago). Open PRs: 29, open issues: 35. Last activity: 24m ago. Community health: 87%. Top contributors: terrelln, Victor-C-Zhang, daniellerozenblit, kevinjzhang, Cyan4973, jlee303, mmandina, felixhandte, zhiningli, iahs and others.