]> git.ipfire.org Git - thirdparty/zlib-ng.git/log
thirdparty/zlib-ng.git
2 days ago[configure] Add support for Intel DPC++/C++ compiler. develop
Mika Lindqvist [Sun, 19 Jul 2026 09:06:52 +0000 (12:06 +0300)] 
[configure] Add support for Intel DPC++/C++ compiler.

2 days agoMinor style cleanup of zng_length_code and zng_dist_code
Hans Kristian Rosbach [Thu, 16 Jul 2026 17:35:50 +0000 (19:35 +0200)] 
Minor style cleanup of zng_length_code and zng_dist_code

2 days agoRemove unnecessary masking of extra bits from mask, the extra bits
Hans Kristian Rosbach [Thu, 16 Jul 2026 14:23:03 +0000 (16:23 +0200)] 
Remove unnecessary masking of extra bits from mask, the extra bits
are outside the range of the data to be masked.

2 days agoOptimize zng_emit_dist by removing base and instead adding mask to extra tables
Hans Kristian Rosbach [Thu, 16 Jul 2026 13:07:05 +0000 (15:07 +0200)] 
Optimize zng_emit_dist by removing base and instead adding mask to extra tables

3 days ago[configure] Fix broken test
Mika Lindqvist [Fri, 17 Jul 2026 17:12:01 +0000 (20:12 +0300)] 
[configure] Fix broken test
* Configuring for ARM gives error message "../configure: 2093: test: -eq: unexpected operator"

6 days agoMinor cleanup of zng_emit_dist()
Hans Kristian Rosbach [Wed, 15 Jul 2026 22:08:13 +0000 (00:08 +0200)] 
Minor cleanup of zng_emit_dist()

6 days agoClean up slide_hash_c code.
Hans Kristian Rosbach [Tue, 14 Jul 2026 21:16:58 +0000 (23:16 +0200)] 
Clean up slide_hash_c code.
Also remove the original loop that GCC is still struggling to
vectorize at -O2.

6 days agoUse the same unroll factor for the copying variant
Adam Stylinski [Fri, 3 Jul 2026 14:07:21 +0000 (10:07 -0400)] 
Use the same unroll factor for the copying variant

We have to have narrower SIMD vectors for all the reasons why memcpy
is slower with 512 bit vectors. Memory bandwidth bound things in both
directions are generally a net loss with 512 bit wide operations for
AVX512. If it's one way, such as in the plain checksum, prefetching can
mostly save you from any penalty felt by downclocking or stalls due to
memory fetch latency.

6 days agoUnroll by 4x instead of 2x on avx512vnni.
Adam Stylinski [Fri, 3 Jul 2026 13:58:36 +0000 (09:58 -0400)] 
Unroll by 4x instead of 2x on avx512vnni.

As it turns out, we weren't limited on execution ports here and to
hide the latency of these we needed to go wider with more separate
parallel accumulations.

This is based on an exploration in the avxvnni version.

6 days agoSkip redundant hash slides for non-chain-walking strategies
Nathan Moin Vaziri [Thu, 18 Jun 2026 05:06:48 +0000 (22:06 -0700)] 
Skip redundant hash slides for non-chain-walking strategies

deflate_quick reads only the head of each hash chain and never walks
prev, while Z_HUFFMAN_ONLY and Z_RLE read neither. Sliding the whole
hash on every window move is wasted work for them. Add a slide_hash_head
functable entry that slides only the head table, so deflate_quick slides
just the head and the huffman and rle strategies skip the slide entirely.

About 8% faster on the level-1 no-CRC deflate benchmark, output unchanged.

6 days agoSkip prev writes in deflate_quick hash inserts
Nathan Moin Vaziri [Thu, 18 Jun 2026 03:33:16 +0000 (20:33 -0700)] 
Skip prev writes in deflate_quick hash inserts

deflate_quick only looks at the head of each hash chain and never walks
prev, so writing the prev links is wasted work. Add head-only insert
helpers and use them in deflate_quick and the level-1 fill_window
catch-up inserts.

The leftover stale prev is safe if the level is later raised mid-stream,
since longest_match never records a match with cur_match >= strstart and
verifies every match by comparison.

7 days agoFix level 9 segfaault on custom HASH_SIZE.
Hans Kristian Rosbach [Tue, 14 Jul 2026 16:12:09 +0000 (18:12 +0200)] 
Fix level 9 segfaault on custom HASH_SIZE.
PS: It still misbehaves on custom sizes, but no longer segfaults.

7 days agoFix missed cleanup in insert_string
Hans Kristian Rosbach [Mon, 13 Jul 2026 20:45:08 +0000 (22:45 +0200)] 
Fix missed cleanup in insert_string

7 days agoRemove extra masking of the hashed value in insert_string.
Hans Kristian Rosbach [Mon, 13 Jul 2026 20:44:08 +0000 (22:44 +0200)] 
Remove extra masking of the hashed value in insert_string.

7 days agoMake sure HASH_BITS gets updated along with HASH_SIZE
Hans Kristian Rosbach [Mon, 13 Jul 2026 21:01:47 +0000 (23:01 +0200)] 
Make sure HASH_BITS gets updated along with HASH_SIZE

7 days agoAdd AVXVNNI support
Adam Stylinski [Sat, 4 Oct 2025 20:01:23 +0000 (16:01 -0400)] 
Add AVXVNNI support

Intel, hopping on the ML all the things band wagon, decided that VNNI
was just _too_ good to not include on their lesser client CPUs without
AVX512. Given how many cycles it saves for the 32 bit widening
operation and how close we already were to something that supports this
sans AVX512, we may as well include support for it. To actually get
maximal ILP for this, this loop had to be unrolled a considerable
amount, but we're finally faster on both P cores and E cores for this
implementation. The gains are minor but measurable.

The copying variant is only faster on E-cores, so it's not being
compiled or used. This may need further testing on MSVC, they have no
definitive "arch" flag for it as far as I can tell.

7 days agoRebuild stale hash chains on deflateParams change
Nathan Moin Vaziri [Mon, 22 Jun 2026 21:21:23 +0000 (14:21 -0700)] 
Rebuild stale hash chains on deflateParams change

deflateParams can leave the chains stale for the new strategy several ways:
the previous strategy didn't maintain them (stored, huffman, or rle), or
crossing the level-9 boundary switched the hash function from integer to
rolling. In each case the new strategy silently dropped match history until
the window refilled.

Replace the stored-only slide/clear fixup with a single staleness check that
rebuilds the chains from the current window with the new hash whenever the new
strategy reads it. The rebuild reconstructs the chains unconditionally, so
deflate_stored no longer needs to defer and count hash slides; drop that
counter.

7 days agoUnify slide_hash_sse2 to follow same style as the avx2 variant.
Hans Kristian Rosbach [Tue, 14 Jul 2026 19:27:56 +0000 (21:27 +0200)] 
Unify slide_hash_sse2 to follow same style as the avx2 variant.

7 days agoUse alignment-safe reads in RVV chunkmemset
Nathan Moin Vaziri [Fri, 10 Jul 2026 17:59:51 +0000 (10:59 -0700)] 
Use alignment-safe reads in RVV chunkmemset

CHUNK_MEMSET_RVV_IMPL read the broadcast value through a plain pointer
cast, but "from" can be at any byte offset in the output window, so the
read may be misaligned. Read the value with zng_memread_* like every
other chunkset implementation. Targets with fast unaligned loads
generate identical code; strict-align targets now get byte-wise loads
instead of a wide load that may trap.

Fixes #1670

Assisted-By: Claude Fable 5 <noreply@anthropic.com>
7 days agoRename hash insert helpers by hash method
Nathan Moin Vaziri [Thu, 18 Jun 2026 03:08:14 +0000 (20:08 -0700)] 
Rename hash insert helpers by hash method

Replace the quick_ prefixed and unmarked insert_string helpers with
names based on the hash method used, insert_knuth and insert_roll,
marking deviations from the common single-position insert: _val for
a caller-supplied hash value and _batch for inserting a run of
positions. Rename UPDATE_HASH_INT to UPDATE_HASH_KNUTH to match.

This covers the callback type, dispatch pointers, and the
insert_string benchmark harness.

7 days agoAdd --benchmark_data_types flag to select data type variants
Nathan Moin Vaziri [Tue, 7 Jul 2026 19:02:32 +0000 (12:02 -0700)] 
Add --benchmark_data_types flag to select data type variants

Register the data-type benchmark variants at runtime instead of
statically, gated by a new --benchmark_data_types flag taking a
comma-separated list of type names or "all". Only text is registered
by default, so the default benchmark count stays at the pre-existing
suite size. Non-text types use reduced size/level ladders (inflate:
16K/128K/1M, deflate: levels 3/6/9 at 128K/1M).

Assisted-By: Claude Fable 5
7 days agoAdd mixed data type to benchmark data generators
Nathan Moin Vaziri [Tue, 7 Jul 2026 03:14:14 +0000 (20:14 -0700)] 
Add mixed data type to benchmark data generators

Literal runs mixed with medium self-referential matches, modeled on the
stream shape of compiled binaries: ~30% literal bytes with near-flat
codes, ~85% literal symbols, ratio ~2.3. Covers the region between
literals (no matches) and the match-dominated types.

Assisted-By: Claude Fable 5
7 days agoAdd literals data type to benchmark data generators
Nathan Moin Vaziri [Tue, 7 Jul 2026 02:12:48 +0000 (19:12 -0700)] 
Add literals data type to benchmark data generators

High-entropy bytes (~6.5 bits/byte) that deflate encodes as Huffman-coded
blocks with almost no matches, filling the gap between text (skewed codes,
root-table hits) and random (stored blocks, decode loop bypassed).

Assisted-By: Claude Fable 5
7 days agoAdd DNA data type to benchmark data generators
Nathan Moinvaziri [Sat, 27 Jun 2026 20:29:47 +0000 (13:29 -0700)] 
Add DNA data type to benchmark data generators

Add a 4-symbol (DNA base) alphabet generator. With only four symbols
nearly every 3-byte prefix collides, producing very long hash chains
while matches stay short, which stresses the longest_match short-match
path that the existing generators do not isolate. Register it for the
deflate and inflate benchmark variants.

Assisted-By: Claude Opus 4.8 <noreply@anthropic.com>
7 days agoCross-vary inflate and deflate benchmarks by input data type
Nathan Moin Vaziri [Mon, 11 May 2026 04:15:47 +0000 (21:15 -0700)] 
Cross-vary inflate and deflate benchmarks by input data type

inflate_bench and deflate_bench now register a separate benchmark per
(variant, data_type) pair so the data type appears in the display name.
inflate yields five benchmarks per size:

  inflate_bench/nocrc/{text,short_match,random,realistic_rgb,striped_rgb}/SIZE

deflate yields five benchmarks per (variant, size, level) — across
level/nocrc/filtered/huffman/rle/fixed — for 280 combinations total:

  deflate_bench/{level,nocrc,filtered,huffman,rle,fixed}/{text,...}/SIZE/LEVEL

Both fixtures share a Dispatch() pattern with an empty SetUp; ->Name()
controls the "/"-separated display. Inflate sizes its compressed buffer
via deflateBound to handle incompressible inputs.

All data generators move to test/test_data_p.h (renamed from
compressible_data_p.h) behind a gen_test_data(test_data_type, bufsize)
dispatcher.

8 days agoRead bits with zero refill latency
Dougall Johnson [Thu, 2 Jul 2026 10:08:56 +0000 (20:08 +1000)] 
Read bits with zero refill latency

Look up the next length code before refilling the bit buffer, so the
refill's load latency overlaps with the table load instead of feeding
it. This is a small but confusing change discussed here:
https://dougallj.wordpress.com/2022/08/26/reading-bits-with-zero-refill-latency/

The loop-entry invariant becomes: hold contains at least the
MAX_LEN_ROOT_BITS (10) bits needed for the first-level length table
lookup. The refill before the loop establishes it, the literal-only
paths consume at most 35 of the 56+ bits from the in-loop refill, and
the distance path's conditional refill threshold is raised by
MAX_LEN_ROOT_BITS so that consuming the distance code and extra bits
(up to MAX_BITS + MAX_DIST_EXTRA_BITS) still leaves enough. The new
MAX_LEN_ROOT_BITS constant replaces the hardcoded 10 at the
state->lenbits assignments in inflate.c and infback.c so the invariant
cannot silently drift.

INFLATE_FAST_MIN_HAVE stays 15: there are still at most two 8-byte
refill reads per iteration, the first at the position validated by the
loop bound (advancing at most 7 bytes), and the pre-loop refill reads
at the entry position (avail_in >= 15) advancing exactly 7 bytes with
bits >= 56 left over, so the first iteration's in-loop refill advances
0 bytes before its read.

Inflate benchmarks on Apple Silicon (clang, Release):

  benchmark_zlib inflate_nocrc/1048576:   139 us -> 121 us  (-13.1%)
  benchmark_zlib small_output_buf/16384:   49 us ->  42 us  (-12.9%)
  zlib-ng sources, level 9:  919 MB/s -> 1042 MB/s  (+13.4%)
  dict/words, level 6:       804 MB/s ->  916 MB/s  (+14.0%)
  static library, level 6:   709 MB/s ->  794 MB/s  (+12.0%)

Assisted-By: Claude Fable 5
8 days agoForce post-indexed loads in NEON compare256
Nathan Moin Vaziri [Mon, 29 Jun 2026 14:51:22 +0000 (07:51 -0700)] 
Force post-indexed loads in NEON compare256

When compare256_neon inlines into longest_match, neither clang nor gcc
keeps the two-stream compare loop post-indexed: both emit a base+offset
address plus a separate add per 16-byte step. On clang this is because
loop strength reduction cannot generate post-increment addressing at
all; its isLegalAddressingMode hook has no way to express it, a
long-standing "TODO: handle pre/postinc" [1][2]. Post-indexed loads are
left to the AArch64 load/store optimizer, a post-isel peephole that only
fires for simple loop shapes [3].

The short-match peel restructured the surrounding code enough to move the
loop out of the shape that peephole recognizes, turning a previously
post-indexed clang loop into the extra-add form and regressing the
striped_rgb benchmark. gcc never post-indexed this loop to begin with,
so it carried the extra add on both develop and the PR.

No source-level spelling avoids it; every C formulation funnels through
the same lowering. Pin the post-indexed form with inline asm: one
self-incrementing pointer reaches the other stream at a constant offset,
folding the +16 advance back into the load. The result is byte-identical
and speeds up striped_rgb on both compilers (M5: clang flips it from a
regression to a win, gcc -3% to -6%).

MSVC ARM64 has no inline asm and keeps the plain intrinsic loop.

[1] https://groups.google.com/g/llvm-dev/c/tmC5Elmi_54
[2] https://tcloud.sjtu.edu.cn/pdf/CGO_2025_Postiz.pdf
[3] https://llvm.org/doxygen/AArch64LoadStoreOptimizer_8cpp_source.html

8 days agoReject short-match candidates with a masked test instead of ctz
Nathan Moinvaziri [Sun, 28 Jun 2026 03:09:05 +0000 (20:09 -0700)] 
Reject short-match candidates with a masked test instead of ctz

A candidate can only improve best_len when its first best_len+1 bytes
all match, so the rejection path does not need the exact mismatch
position. Compute a loop-invariant mask of those bytes and reject with a
single AND and zero-test, running ctz only on the rare accepting
candidate. This keeps the multi-cycle ctz off the hot rejection path,
which helps dense-chain inputs (low-alphabet data, slow cores) while
leaving compressed output unchanged.

8 days agoPeel first candidate out of the short-match chain walk
Nathan Moin Vaziri [Sun, 28 Jun 2026 18:06:15 +0000 (11:06 -0700)] 
Peel first candidate out of the short-match chain walk

Unroll the first candidate check and its chain advance ahead of the
loop so its match case is the fall-through into compare256, which the
fast levels hit on nearly every call, and single-candidate chains
(barely-compressible data) run straight-line with no loop-entry
overhead. Longer chains continue into a self-contained rejection loop,
costing one predictable branch per rejected candidate instead of three,
and the compiler lays out each path for its own hot case.

Improves level 9 by 1.5-2% on Apple M5 and trims the mid levels on
barely-compressible data. Compressed output is byte-identical.

8 days agoShort-circuit longest_match on short candidates via XOR and ctz
Nathan Moin Vaziri [Sat, 11 Apr 2026 23:41:04 +0000 (16:41 -0700)] 
Short-circuit longest_match on short candidates via XOR and ctz

When best_len is under 8, the whole candidate match fits in the
first 8 bytes, so a single load XORed against scan_start and run
through ctz gives the exact match length with no COMPARE256 call
and no separate tail sentinel. The best_len-to-offset mapping
collapses to a single subtract since the graduated sizeof(uint32_t)
and sizeof(uint64_t) brackets no longer cover anything distinct.

Benefits every deflate strategy that calls longest_match: level 3
gains 10-12% at 128KB+ inputs and levels 1, 6, and 7 each trim 1-3%.
Compressed output is byte-identical across corpora.

Prior art: zlib-rs first applied the same XOR+ctz technique in
trifectatechfoundation/zlib-rs#284.

Co-authored-by: Brian Pane <brianp@brianp.net>
11 days agoAdd ABI files for loongarch64 target and update create-abi-files.sh script
Vladislav Shchapov [Sat, 4 Jul 2026 14:18:56 +0000 (19:18 +0500)] 
Add ABI files for loongarch64 target and update create-abi-files.sh script

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
11 days agoFix this compilation issue for non-windows machines
Adam Stylinski [Sun, 5 Jul 2026 15:31:23 +0000 (11:31 -0400)] 
Fix this compilation issue for non-windows machines

I've been manually fixing this up for a bit. We're on C++ so let's just
use STL's functions here, which should compile down to min and max
instructions.

2 weeks agoAdd Win32 CPU scheduling flags to benchmark suite
Nathan Moin Vaziri [Mon, 29 Jun 2026 01:19:24 +0000 (18:19 -0700)] 
Add Win32 CPU scheduling flags to benchmark suite

Add Windows-only command-line flags to reduce benchmark variance.
--benchmark_cpu_affinity pins the process to a taskset-style CPU list,
--benchmark_no_power_throttling opts out of EcoQoS to keep full clock on
performance cores, and --benchmark_priority sets the process priority
class. Document the custom arguments in a table in the README.

Assisted-By: Claude Opus 4.8
2 weeks agoset memory error on oversized gzbuffer request and simplify gz_buffer_alloc types
dxbjavid [Wed, 24 Jun 2026 15:56:41 +0000 (21:26 +0530)] 
set memory error on oversized gzbuffer request and simplify gz_buffer_alloc types

2 weeks agocap gzbuffer request at 1 GiB in the api
dxbjavid [Tue, 23 Jun 2026 13:42:18 +0000 (19:12 +0530)] 
cap gzbuffer request at 1 GiB in the api

move the size limit into gzbuffer itself: zng_gzbuffer rejects requests
over 1 GiB with -1 while the compat gzbuffer silently clamps to 1 GiB,
keeping the checks next to the api like the rest of zlib-ng. with want
bounded there the gz_buffer_alloc backstop is no longer needed, so drop
it and note the limit in the zlib-ng.h docs.

2 weeks agoshorten gz_buffer_alloc overflow comment
dxbjavid [Wed, 17 Jun 2026 05:02:09 +0000 (10:32 +0530)] 
shorten gz_buffer_alloc overflow comment

2 weeks agoadd explicit cast when storing want in state->size
dxbjavid [Sun, 14 Jun 2026 04:34:38 +0000 (10:04 +0530)] 
add explicit cast when storing want in state->size

2 weeks agoCap gz_buffer_alloc size at INT_MAX accounting for allocator overhead
dxbjavid [Fri, 5 Jun 2026 12:05:43 +0000 (17:35 +0530)] 
Cap gz_buffer_alloc size at INT_MAX accounting for allocator overhead

2 weeks agofix integer overflow in gz_buffer_alloc buffer sizing
dxbjavid [Fri, 5 Jun 2026 09:49:42 +0000 (15:19 +0530)] 
fix integer overflow in gz_buffer_alloc buffer sizing

2 weeks agoAdd shell script to update/refresh ABI files under Ubuntu
Mika Lindqvist [Sun, 21 Jun 2026 08:42:02 +0000 (11:42 +0300)] 
Add shell script to update/refresh ABI files under Ubuntu
* Add some missing ABI files for 64-bit targets

2 weeks agoFix finding gz files.
Mika Lindqvist [Thu, 18 Jun 2026 21:30:36 +0000 (00:30 +0300)] 
Fix finding gz files.

2 weeks agoForce inline compare256 helpers
Nathan Moin Vaziri [Tue, 30 Jun 2026 19:57:34 +0000 (12:57 -0700)] 
Force inline compare256 helpers

The compare256_*_static helpers are textually included into match_tpl.h
to specialize each longest_match variant, and compare256_rle_* serve the
RLE path the same way. At -O3 clang declines to inline the larger fully
unrolled bodies (scalar and NEON), emitting an out-of-line call with
register spills around it on the hot path. Mark them Z_FORCEINLINE so
each inlines into its consumer as intended. GCC already inlines them.

Assisted-By: Claude Opus 4.8
2 weeks agoBump actions/checkout from 6 to 7
dependabot[bot] [Wed, 1 Jul 2026 07:04:04 +0000 (07:04 +0000)] 
Bump actions/checkout from 6 to 7

Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2 weeks agoBump actions/cache from 5 to 6
dependabot[bot] [Wed, 1 Jul 2026 07:03:56 +0000 (07:03 +0000)] 
Bump actions/cache from 5 to 6

Bumps [actions/cache](https://github.com/actions/cache) from 5 to 6.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
3 weeks agoFix build with macOS 26.
Mika Lindqvist [Tue, 23 Jun 2026 15:04:53 +0000 (18:04 +0300)] 
Fix build with macOS 26.

4 weeks agoExtend the MSVC 2015 AVX2/AVX512 workaround to MSVC 2017.
David Korth [Mon, 22 Jun 2026 22:36:55 +0000 (18:36 -0400)] 
Extend the MSVC 2015 AVX2/AVX512 workaround to MSVC 2017.

The 32-bit MSVC 2015 debug build randomly crashes without this because
the stack ends up not being 16-byte aligned, and MSVC adds a vmovdqa
instruction.

MSVC 2022 and 2026 align the stack properly before using vmovdqa.

4 weeks agoAdd Adler32 ARM NEON DotProd variant
Nathan Moinvaziri [Wed, 18 Mar 2026 16:41:49 +0000 (09:41 -0700)] 
Add Adler32 ARM NEON DotProd variant

Introduce a dotprod-accelerated Adler-32 using vdotq_u32 for both the
byte sum (s1) and the position-weighted sum (s2). Four independent
accumulator sets break the dependency chains between successive dotprod
instructions, allowing the pipeline to fill without stalling on results
from the prior iteration.

On Apple M3, the dotprod path is roughly 49% faster than the standard
NEON implementation for inputs above 32 bytes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4 weeks agoAdd Adler32 ARM NEON wrapper that includes template
Nathan Moinvaziri [Wed, 18 Mar 2026 16:36:55 +0000 (09:36 -0700)] 
Add Adler32 ARM NEON wrapper that includes template

Create adler32_neon.c as a thin wrapper around adler32_neon_tpl.h,
providing the exported adler32_neon and adler32_copy_neon functions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4 weeks agoRefactor Adler32 ARM NEON into a reusable template
Nathan Moinvaziri [Wed, 18 Mar 2026 16:36:34 +0000 (09:36 -0700)] 
Refactor Adler32 ARM NEON into a reusable template

Move the core adler32_copy_impl function from adler32_neon.c into
adler32_neon_tpl.h so that it may be included by variant-specific
source files compiled with different instruction set flags.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4 weeks agoUse vaddvq_u32 for adler32 NEON horizontal reduction
Nathan Moin Vaziri [Tue, 31 Mar 2026 20:12:33 +0000 (13:12 -0700)] 
Use vaddvq_u32 for adler32 NEON horizontal reduction

Replace interleaved pairwise reduction with vaddvq_u32 to break the
dependency chain between s1 and s2 modulo computations. The original
code merged both accumulators through a shared addp, serializing the
subsequent umull/lsr/msub chains. Independent reductions allow them
to execute in parallel.

On AArch64 this maps to the ADDV instruction. A compatibility shim
in neon_intrins.h emulates this on 32-bit ARM using vadd and vpadd.

4 weeks ago[CMake] Add toolchain files for cross-compiling ARM with Clang.
Mika Lindqvist [Fri, 19 Jun 2026 14:19:48 +0000 (17:19 +0300)] 
[CMake] Add toolchain files for cross-compiling ARM with Clang.

4 weeks agoAdd missing return after SkipWithError in benchmarks
Nathan Moin Vaziri [Sun, 21 Jun 2026 19:17:25 +0000 (12:17 -0700)] 
Add missing return after SkipWithError in benchmarks

SkipWithError marks the run skipped but does not return, so these
fixtures fell through into the wrapper that drives the benchmark loop.
The loop body is skipped once the error is set, so the change is
behavior neutral, but it matches the surrounding skip cases that
already return and Google Benchmark's documented contract that exiting
the scope is the caller's responsibility. It also keeps the skip
correct if a fixture later does work before the loop.

Assisted-By: Claude Opus 4.8
4 weeks agoFix type mismatch errors in fuzzers.
Mika T. Lindqvist [Fri, 19 Jun 2026 18:53:50 +0000 (21:53 +0300)] 
Fix type mismatch errors in fuzzers.

4 weeks agoAdd Z_RESTRICT to zng_memcmp functions
Mika Lindqvist [Fri, 19 Jun 2026 16:58:00 +0000 (19:58 +0300)] 
Add Z_RESTRICT to zng_memcmp functions
* Use zng_memread and zng_memwrite functions with Visual C++ too to allow
  unaligned memory access

4 weeks ago[CI] Test Visual C++ 2026 with ZLIB_COMPAT and benchmarks to catch type mismatches.
Mika Lindqvist [Thu, 18 Jun 2026 11:15:44 +0000 (14:15 +0300)] 
[CI] Test Visual C++ 2026 with ZLIB_COMPAT and benchmarks to catch type mismatches.

4 weeks agoFix type mismatch in benchmark_compress.cc.
Mika Lindqvist [Thu, 18 Jun 2026 11:03:49 +0000 (14:03 +0300)] 
Fix type mismatch in benchmark_compress.cc.

4 weeks ago[CI] Add coveralls as trusted formula for Homebrew under MacOS
Mika Lindqvist [Wed, 17 Jun 2026 21:23:23 +0000 (00:23 +0300)] 
[CI] Add coveralls as trusted formula for Homebrew under MacOS
* Homebrew 6.0.0 requires explicit trust when installing formulae from
  third-party taps (repositories)

5 weeks agoCleanup deflate_quick variable reuse and call signatures
Nathan Moin Vaziri [Tue, 12 May 2026 06:24:09 +0000 (23:24 -0700)] 
Cleanup deflate_quick variable reuse and call signatures

Drop the lc local: the four-byte window read is hoisted above the
match-search branch, and the literal-emit takes the low byte of
str_val directly so the short-lookahead arm no longer needs its own
load.  Pass strstart into quick_start_block and quick_end_block so
they no longer reach into s for block_start.  In the early-finish
arm, pass 1 to quick_start_block since last is known to be 1.

5 weeks agoHoist strstart and lookahead to locals in deflate strategies
Nathan Moin Vaziri [Tue, 12 May 2026 05:11:26 +0000 (22:11 -0700)] 
Hoist strstart and lookahead to locals in deflate strategies

Lift s->strstart and s->lookahead into function-local variables in
deflate_quick, deflate_huff, and deflate_rle, synced back to s before
external callouts that observe them (fill_window, longest_match,
FLUSH_BLOCK, returns) and reloaded after callouts that mutate them.

5 weeks agoUse broadcast chunk store instead of memset for dist=1 on NEON/AVX2/AVX-512
Nathan Moinvaziri [Sun, 10 May 2026 08:05:49 +0000 (01:05 -0700)] 
Use broadcast chunk store instead of memset for dist=1 on NEON/AVX2/AVX-512

Benchmarks show broadcasting the byte into a vector register and
falling through to the chunk store loop beats libc memset for the
short lengths common in inflate output (29-58% on AVX-512, 15-26%
on AVX2, 33% on NEON at len=8).

In 49a6bb5d, chunkmemset_1 was replaced with memset under the
assumption that libc memset would be at least as fast. According
to benchmarking, this isn't true in all cases.

5 weeks agoWrap AVX-512 mask intrinsics and use them in CHUNKMEMSET
Nathan Moinvaziri [Sun, 10 May 2026 08:05:11 +0000 (01:05 -0700)] 
Wrap AVX-512 mask intrinsics and use them in CHUNKMEMSET

5 weeks agoRoute CHUNKMEMSET to CHUNKCOPY when dist >= len
Nathan Moin Vaziri [Sun, 10 May 2026 01:03:20 +0000 (18:03 -0700)] 
Route CHUNKMEMSET to CHUNKCOPY when dist >= len

When dist >= len the source bytes don't overlap the destination, so no pattern repeat is needed and CHUNKCOPY produces the same output. Extends the existing `dist >= sizeof(chunk_t)` shortcut so archs with chunk_t > 8 also catch dist in [chunk_t/2, chunk_t-1] with small lengths.

5 weeks agoSkip CHUNKMEMSET loops when length fits in one chunk
Nathan Moin Vaziri [Sun, 10 May 2026 00:24:55 +0000 (17:24 -0700)] 
Skip CHUNKMEMSET loops when length fits in one chunk

When len <= sizeof(chunk_t) a single storechunk on chunk_load gives the same output as the two while-loops + tail. The over-write of chunk_t - len bytes lies in caller headroom.

5 weeks agoInline CHUNKMEMSET tail with bit-decomposed stores
Nathan Moin Vaziri [Sun, 10 May 2026 00:24:24 +0000 (17:24 -0700)] 
Inline CHUNKMEMSET tail with bit-decomposed stores

Replace variable-length memcpy with bitmask-gated fixed-size copies (16 + 8 + 4 + 2 + 1) so the compiler can inline each as a direct store instead of a libc call.

5 weeks agoAdd chunkmemset benchmark
Nathan Moin Vaziri [Sun, 10 May 2026 00:23:53 +0000 (17:23 -0700)] 
Add chunkmemset benchmark

Args span every dispatch arc in CHUNKMEMSET — dist=1 memset, dist>=chunk_t CHUNKCOPY, fast dist=2/4/8/16, GET_CHUNK_MAG, the unrolled loops, and the trailing remainder. Registered against chunkmemset_safe_{c,neon,sse2,ssse3,avx2,avx512,power8,rvv,lsx,lasx} where the symbol is built.

5 weeks agoRemove ptrdiff_t configure/cmake detection
Nathan Moin Vaziri [Thu, 16 Apr 2026 06:39:28 +0000 (23:39 -0700)] 
Remove ptrdiff_t configure/cmake detection

ptrdiff_t is defined in <stddef.h> since C89 and is guaranteed to
exist on any C99+ compiler. zlib-ng requires C99, so the build-time
check and the fallback typedef in zconf headers are unnecessary.

5 weeks agoAdd LIKELY / UNLIKELY hints to LONGEST_MATCH.
Hans Kristian Rosbach [Wed, 10 Jun 2026 13:13:58 +0000 (15:13 +0200)] 
Add LIKELY / UNLIKELY hints to LONGEST_MATCH.
Based on CI/Coveralls data and local benchmarking.

5 weeks agoUnify inconsistent handling of GZBUFSIZE, and update documentation.
Hans Kristian Rosbach [Wed, 10 Jun 2026 16:58:35 +0000 (18:58 +0200)] 
Unify inconsistent handling of GZBUFSIZE, and update documentation.

5 weeks agoAdd -mbmi to AVX2 and AVX512 compile flags
Nathan Moin Vaziri [Thu, 11 Jun 2026 23:38:57 +0000 (16:38 -0700)] 
Add -mbmi to AVX2 and AVX512 compile flags

The AVX2 and AVX512 flags enable BMI2 but not BMI1, and TZCNT is a
BMI1 instruction. GCC emits the rep bsf encoding that executes as
TZCNT on BMI hardware regardless, but clang gates on the feature bit
and emits plain BSF, which is slower on AMD. Every CPU with AVX2 also
has BMI1, so the flag only affects code already behind AVX2 runtime
detection.

Assisted-By: Claude Opus 4.8 (1M context)
5 weeks agoReplace hash calculations with macros in insert_string_p.h
Hans Kristian Rosbach [Thu, 11 Jun 2026 12:27:32 +0000 (14:27 +0200)] 
Replace hash calculations with macros in insert_string_p.h

5 weeks agoRemove unused functions
Hans Kristian Rosbach [Wed, 10 Jun 2026 21:10:08 +0000 (23:10 +0200)] 
Remove unused functions

5 weeks agoClean up and simplify insert_string code.
Hans Kristian Rosbach [Wed, 10 Jun 2026 18:55:37 +0000 (20:55 +0200)] 
Clean up and simplify insert_string code.

5 weeks agoRemove obsolete templating of insert_string functions.
Hans Kristian Rosbach [Wed, 10 Jun 2026 18:30:35 +0000 (20:30 +0200)] 
Remove obsolete templating of insert_string functions.

5 weeks ago[CI] Add configure workflow for Windows AMD64 with Clang.
Mika Lindqvist [Mon, 1 Jun 2026 18:06:25 +0000 (21:06 +0300)] 
[CI] Add configure workflow for Windows AMD64 with Clang.

5 weeks agoAdd branch prediction hints to deflate strategy hot loops
Nathan Moin Vaziri [Fri, 15 May 2026 23:22:01 +0000 (16:22 -0700)] 
Add branch prediction hints to deflate strategy hot loops

The deflate strategies were inconsistent about branch-prediction hints
on their per-iteration lookahead checks. deflate_quick marked both the
window-refill path unlikely and the steady-state path likely;
deflate_slow marked only the steady-state path; deflate_fast and
deflate_medium marked neither, leaving the compiler to guess the inner
loop's hot/cold block placement.

Mark the window-refill and end-of-input paths unlikely and the
steady-state path likely across deflate_fast, deflate_slow,
deflate_medium, deflate_rle, and deflate_huff, following deflate_quick,
so the rarely-taken refill block stays off the hot fall-through path
and block placement is consistent across all strategies.

6 weeks agoImplement coderabbitai suggested cleanup and improvements for utils/CMakeLists.txt
Hans Kristian Rosbach [Tue, 9 Jun 2026 14:24:11 +0000 (16:24 +0200)] 
Implement coderabbitai suggested cleanup and improvements for utils/CMakeLists.txt

6 weeks agoAdd utils/README.md
Hans Kristian Rosbach [Tue, 9 Jun 2026 13:41:28 +0000 (15:41 +0200)] 
Add utils/README.md

6 weeks agoMove makecrct, makefixed and maketrees to utils/ folder.
Hans Kristian Rosbach [Tue, 9 Jun 2026 13:25:19 +0000 (15:25 +0200)] 
Move makecrct, makefixed and maketrees to utils/ folder.

6 weeks agoMove minideflate.c and minigzip.c to utils/ folder, now always building
Hans Kristian Rosbach [Tue, 9 Jun 2026 13:13:08 +0000 (15:13 +0200)] 
Move minideflate.c and minigzip.c to utils/ folder, now always building
these, no longer depending on tests being enabled.

6 weeks agoFix warnings about BRAID_W/BRAID_N being undefined.
Hans Kristian Rosbach [Mon, 8 Jun 2026 17:48:55 +0000 (19:48 +0200)] 
Fix warnings about BRAID_W/BRAID_N being undefined.

6 weeks agoFix warnings about __CYGWIN__ being undefined.
Hans Kristian Rosbach [Mon, 8 Jun 2026 17:48:09 +0000 (19:48 +0200)] 
Fix warnings about __CYGWIN__ being undefined.

6 weeks agoFix warnings about BIG_ENDIAN/LITTLE_ENDIAN being undefined
Hans Kristian Rosbach [Mon, 8 Jun 2026 17:46:48 +0000 (19:46 +0200)] 
Fix warnings about BIG_ENDIAN/LITTLE_ENDIAN being undefined

6 weeks ago[CI] Add configure workflow for Windows ARM64 with clang.
Mika T. Lindqvist [Sun, 31 May 2026 11:32:41 +0000 (14:32 +0300)] 
[CI] Add configure workflow for Windows ARM64 with clang.

6 weeks agoFix warnings triggered by NVHPC/nvc.
Mika T. Lindqvist [Fri, 22 May 2026 11:14:50 +0000 (14:14 +0300)] 
Fix warnings triggered by NVHPC/nvc.

6 weeks agoReject asymmetric C vs C++ machine flags
Nathan Moin Vaziri [Wed, 20 May 2026 00:08:36 +0000 (17:08 -0700)] 
Reject asymmetric C vs C++ machine flags

Different machine flags in C vs C++ flags produce undefined-reference
link failures.

7 weeks ago[CI] Add ARM64 version of MinGW64 with gcc.
Mika T. Lindqvist [Sun, 31 May 2026 10:45:47 +0000 (13:45 +0300)] 
[CI] Add ARM64 version of MinGW64 with gcc.

7 weeks agogzread: Fix compilation on AIX
Aelin Reidel [Fri, 29 May 2026 04:27:48 +0000 (06:27 +0200)] 
gzread: Fix compilation on AIX

7 weeks ago[CI] Add NVHPC to CMake workflow.
Mika Lindqvist [Wed, 20 May 2026 22:57:39 +0000 (01:57 +0300)] 
[CI] Add NVHPC to CMake workflow.

7 weeks agoLCC: Suppress warnings in Google Benchmark.
Vladislav Shchapov [Sun, 17 May 2026 17:01:13 +0000 (22:01 +0500)] 
LCC: Suppress warnings in Google Benchmark.

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
7 weeks agoFix warnings variable set but not used.
Vladislav Shchapov [Sun, 17 May 2026 15:55:05 +0000 (20:55 +0500)] 
Fix warnings variable set but not used.

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
7 weeks agoFix warning label followed by a declaration is a C23 extension.
Vladislav Shchapov [Sun, 17 May 2026 14:54:51 +0000 (19:54 +0500)] 
Fix warning label followed by a declaration is a C23 extension.

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
7 weeks agoEnable -Werror in GCC and Clang.
Vladislav Shchapov [Sun, 17 May 2026 14:29:37 +0000 (19:29 +0500)] 
Enable -Werror in GCC and Clang.

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
7 weeks agoAlways check that distance is too far back in inflateBack.
Mika T. Lindqvist [Tue, 19 May 2026 13:06:46 +0000 (16:06 +0300)] 
Always check that distance is too far back in inflateBack.

8 weeks agoMake macro redefinition fatal with LCC.
Mika T. Lindqvist [Sun, 17 May 2026 19:50:26 +0000 (22:50 +0300)] 
Make macro redefinition fatal with LCC.

8 weeks agoRemove dead unlink forward declaration in minigzip tests
Nathan Moin Vaziri [Fri, 17 Apr 2026 07:07:23 +0000 (00:07 -0700)] 
Remove dead unlink forward declaration in minigzip tests

Both files include zbuild.h which now unconditionally defines
_LARGEFILE64_SOURCE, making the !defined(_LARGEFILE64_SOURCE) clause
always false and the whole block unreachable. The upstream-zlib
purpose was forward-declaring unlink on platforms without unistd.h
that aren't Windows, but zlib-ng's supported platforms either have
unistd.h or define _WIN32.

8 weeks agoRemove dead NO_FSEEKO detection
Nathan Moin Vaziri [Fri, 17 Apr 2026 06:43:59 +0000 (23:43 -0700)] 
Remove dead NO_FSEEKO detection

zlib-ng never calls fseeko; gzlib.c was rewritten to use
lseek / lseek64 / _lseeki64 directly. The NO_FSEEKO define is not
referenced by any source file, so the CMake check_function_exists
and matching configure probe are dead code.

8 weeks agoDrop dead glibc feature-macro juggling from gzguts.h
Nathan Moin Vaziri [Fri, 17 Apr 2026 06:58:18 +0000 (23:58 -0700)] 
Drop dead glibc feature-macro juggling from gzguts.h

_LARGEFILE_SOURCE enables fseeko/ftello, which zlib-ng never calls
(gzlib.c uses lseek/lseek64/_lseeki64 directly). The _FILE_OFFSET_BITS
and _TIME_BITS undefs were defensive against a consumer-provided
-D_FILE_OFFSET_BITS=64 leaking into library internals, but they sat
after zbuild.h had already included <stdio.h> so they never affected
system-header sizing. The zlib.h gzopen->gzopen64 remap they were
guarding against is already blocked by the Z_INTERNAL gate for
library builds.

8 weeks agoInclude zbuild.h first in tools and tests
Nathan Moin Vaziri [Wed, 13 May 2026 21:12:12 +0000 (14:12 -0700)] 
Include zbuild.h first in tools and tests

zbuild.h defines _LARGEFILE64_SOURCE, but the macro only takes effect
if seen before any system header. The tools and fuzz/test files that
included <stdio.h> ahead of zbuild.h processed <features.h> without it,
so _LFS64_LARGEFILE never got set and z_off64_t expanded to an unknown
off64_t once LFS64 detection moved out of the build system.

Reorder so zbuild.h precedes any system header, and drop the redundant
<stdio.h>/<stdlib.h>/<string.h> includes that zbuild.h already pulls in.

8 weeks agoMove LFS64 detection from build system to C preprocessor
Nathan Moin Vaziri [Fri, 17 Apr 2026 06:42:59 +0000 (23:42 -0700)] 
Move LFS64 detection from build system to C preprocessor

zbuild.h now defines _LARGEFILE64_SOURCE before any system header, so
glibc exposes off64_t and lseek64 where available. The _LFS64_LARGEFILE
check already in zconf.h handles per-platform gating. Drops the
redundant -D__USE_LARGEFILE64 (internal glibc macro, set automatically)
and the unused __off64_t probe that only wrote to HAVE___OFF64_T.

The configure script's _off64_t probe was log-only and the off64_t=yes
path assumed fseeko exists without testing; both are removed in favor
of the standalone fseeko check.

2 months agoIf runtime CPU detection is disabled then define native_* macros to generic fallbacks...
Vladislav Shchapov [Sat, 16 May 2026 04:38:14 +0000 (09:38 +0500)] 
If runtime CPU detection is disabled then define native_* macros to generic fallbacks only if native_* macros is not previous defined.

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>