[lld] [lld][ELF][test] Accept zlib-ng compressed size (PR #206880)
Mark Zhuang via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 1 20:49:00 PDT 2026
zqb-all wrote:
<details> <summary>Reproduction script (needs cmake, cc, curl)</summary>
```bash
#!/usr/bin/env bash
# Reproduce the zlib vs zlib-ng level-1 deflate size difference behind
# lld/test/ELF/compressed-debug-level.test, and show it is an intentional
# speed/ratio tradeoff (deflate_quick), not a RISC-V or zlib-ng bug.
# Requirements: cmake, cc, curl. Runs entirely under /tmp/zngrepro.
set -e
cd /tmp && rm -rf zngrepro && mkdir zngrepro && cd zngrepro
# 1) Fetch zlib-ng 2.3.2 source (the version Bianbu ships).
curl -fsSL --retry 5 --retry-all-errors -o zlib-ng-2.3.2.tar.gz \
https://codeload.github.com/zlib-ng/zlib-ng/tar.gz/refs/tags/2.3.2
tar xzf zlib-ng-2.3.2.tar.gz
SRC=$PWD/zlib-ng-2.3.2
# 2) Build A: stock defaults. At level 1, zlib-ng dispatches to deflate_quick
# (configuration_table[1] in deflate.c).
cmake -S "$SRC" -B build-quick -DZLIB_COMPAT=ON -DCMAKE_BUILD_TYPE=Release >/dev/null 2>&1
cmake --build build-quick -j"$(nproc)" >/dev/null 2>&1
# 3) Build B: -DNO_QUICK_STRATEGY. This disables deflate_quick, so level 1
# falls back to deflate_fast -- the same strategy stock zlib uses.
cmake -S "$SRC" -B build-noquick -DZLIB_COMPAT=ON -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_FLAGS="-DNO_QUICK_STRATEGY" >/dev/null 2>&1
cmake --build build-noquick -j"$(nproc)" >/dev/null 2>&1
# 4) Minimal reproducer: deflate the exact 36-byte .debug_info payload from the
# lld test at level 1. Section size reported by llvm-readelf = deflate stream
# + 12-byte Elf32_Chdr, so we add 12 to match the values seen in the test.
cat > defl.c <<'EOF'
#include <stdio.h>
#include <string.h>
#include <zlib.h>
static const unsigned char in[] = {
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x01,0x01,0x02,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x01,0x01,0x02,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x01,0x01,0x02,0x01};
int main(void){
unsigned char out[256]; z_stream s; memset(&s,0,sizeof s);
deflateInit(&s,1); /* level 1, same as ld.lld default */
s.next_in=(unsigned char*)in; s.avail_in=sizeof in;
s.next_out=out; s.avail_out=sizeof out;
deflate(&s,Z_FINISH);
printf("%-16s deflate(level1)=%2lu bytes -> ELF section size 0x%lx\n",
zlibVersion(), (unsigned long)s.total_out,
(unsigned long)s.total_out+12); /* + Elf32_Chdr */
deflateEnd(&s); return 0;
}
EOF
cc defl.c -o defl_quick -I"$SRC" -Ibuild-quick -Lbuild-quick -lz -Wl,-rpath,"$PWD/build-quick"
cc defl.c -o defl_noquick -I"$SRC" -Ibuild-noquick -Lbuild-noquick -lz -Wl,-rpath,"$PWD/build-noquick"
cc defl.c -o defl_sys -lz # link against the system's stock zlib
echo "================ Root cause: level-1 deflate of the 36-byte payload ================"
echo -n "stock zlib (system) : "; ./defl_sys
echo -n "zlib-ng 2.3.2 deflate_quick : "; ./defl_quick
echo -n "zlib-ng 2.3.2 NO_QUICK_STRATEGY: "; ./defl_noquick
echo "host arch: $(uname -m)"
# 5) Tradeoff: deflate_quick trades ratio for speed. Compare stock zlib vs
# zlib-ng at level 1 (deflate_quick) and level 2 (leaves deflate_quick)
# on realistic inputs, measuring both output size and throughput.
cat > bench.c <<'EOF'
#define _POSIX_C_SOURCE 199309L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <zlib.h>
static double now(void){struct timespec t;clock_gettime(CLOCK_MONOTONIC,&t);return t.tv_sec+t.tv_nsec*1e-9;}
int main(int argc,char**argv){
int level=atoi(argv[2]);
FILE*f=fopen(argv[1],"rb"); fseek(f,0,SEEK_END); long n=ftell(f); fseek(f,0,SEEK_SET);
unsigned char*in=malloc(n); if(fread(in,1,n,f)!=(size_t)n)return 2; fclose(f);
unsigned long bound=compressBound(n); unsigned char*out=malloc(bound);
unsigned long outlen=bound; compress2(out,&outlen,in,n,level);
long budget=200L*1024*1024; int iters=(int)(budget/(n?n:1)); if(iters<3)iters=3; if(iters>200000)iters=200000;
double t0=now(); for(int i=0;i<iters;i++){unsigned long ol=bound; compress2(out,&ol,in,n,level);} double dt=now()-t0;
printf(" %-14s lvl=%d out=%8lu ratio=%7.3f %8.1f MB/s\n",
zlibVersion(),level,outlen,(double)n/outlen,(double)n*iters/dt/1e6);
return 0;
}
EOF
cc bench.c -o bench_sys -O2 -lz
cc bench.c -o bench_ng -O2 -I"$SRC" -Ibuild-quick -Lbuild-quick -lz -Wl,-rpath,"$PWD/build-quick"
# Inputs: highly-repetitive text, natural source text, and a real binary.
yes "$(printf '%.0s/' $(seq 1 70))" 2>/dev/null | head -c 4500000 > in_repetitive.txt
cat "$SRC"/*.c "$SRC"/*.h > in_source.txt
cp "$(command -v cc)" in_binary.bin
echo
echo "================ Tradeoff: size vs throughput (stock zlib vs zlib-ng) ================"
for f in in_repetitive.txt in_source.txt in_binary.bin; do
for lvl in 1 2; do
echo "input=$f level=$lvl"
./bench_sys "$f" "$lvl"
./bench_ng "$f" "$lvl"
done
done
```
</details>
result:
```
$ bash ./zlibng_repro.sh
================ Root cause: level-1 deflate of the 36-byte payload ================
stock zlib (system) : 1.2.11 deflate(level1)=18 bytes -> ELF section size 0x1e
zlib-ng 2.3.2 deflate_quick : 1.3.1.zlib-ng deflate(level1)=20 bytes -> ELF section size 0x20
zlib-ng 2.3.2 NO_QUICK_STRATEGY: 1.3.1.zlib-ng deflate(level1)=17 bytes -> ELF section size 0x1d
host arch: x86_64
================ Tradeoff: size vs throughput (stock zlib vs zlib-ng) ================
input=in_repetitive.txt level=1
1.2.11 lvl=1 out= 41167 ratio=109.311 671.2 MB/s
1.3.1.zlib-ng lvl=1 out= 78029 ratio= 57.671 2882.4 MB/s
input=in_repetitive.txt level=2
1.2.11 lvl=2 out= 41167 ratio=109.311 483.8 MB/s
1.3.1.zlib-ng lvl=2 out= 28803 ratio=156.234 3344.0 MB/s
input=in_source.txt level=1
1.2.11 lvl=1 out= 380828 ratio= 2.656 62.8 MB/s
1.3.1.zlib-ng lvl=1 out= 486395 ratio= 2.080 152.7 MB/s
input=in_source.txt level=2
1.2.11 lvl=2 out= 366271 ratio= 2.762 79.1 MB/s
1.3.1.zlib-ng lvl=2 out= 355518 ratio= 2.845 130.9 MB/s
input=in_binary.bin level=1
1.2.11 lvl=1 out= 369680 ratio= 2.512 47.0 MB/s
1.3.1.zlib-ng lvl=1 out= 446865 ratio= 2.078 147.8 MB/s
input=in_binary.bin level=2
1.2.11 lvl=2 out= 362590 ratio= 2.561 56.4 MB/s
1.3.1.zlib-ng lvl=2 out= 370760 ratio= 2.505 85.2 MB/s
```
https://github.com/llvm/llvm-project/pull/206880
More information about the llvm-commits
mailing list