zstd
zstd copied to clipboard
Weird code size when -mbmi2 or -mno-bmi2 is specified
Describe the bug
I compile libzstd in folder lib
with:
make ZSTD_LIB_COMPRESSION=0 ZSTD_LIB_DICTBUILDER=0 ZSTD_LIB_DEPRECATED=0 ZSTD_LEGACY_SUPPORT=0 ZSTD_NO_UNUSED_FUNCTIONS=1 DYNAMIC_BMI2=0 CC=clang
When I add CFLAGS
on command line and override BMI2 manually, I get the following lib sizes:
CFLAGS="" -rw-rw-r-- 209504 libzstd.a
CFLAGS="-mbmi2" -rw-rw-r-- 270344 libzstd.a
CFLAGS="-mno-bmi2" -rw-rw-r-- 391528 libzstd.a
All three libraries have different code size. This does not make sense to me, as I would expect either -mbmi2
or -mno-bmi2
to match the default code size, as DYNAMIC_BMI2=0
is specified (note that I'm seeing the same behavior and exactly same code size even with DYNAMIC_BMI2=1
).
Also note that GCC produces roughly the same results.
To Reproduce
Compile libzstd in folder lib
with the supplied make
command
Expected behavior
Supplying either -mbmi2
or -mno-bmi2
would match the default code size.
Is this behavior expected? Am I overriding BMI2 correctly?
Desktop (please complete the following information):
- OS: Ubuntu
- Version: 23
- Compiler: Clang-15, GCC-12
- Flags: Default
- Other relevant hardware specs: Zen1
- Build system: Make
Could bmi2
also enable avx2
transparently ?
I managed to find the root cause of the issue.
The makefile contains following line https://github.com/facebook/zstd/blob/dev/lib/libzstd.mk#L95 , the ?=
causes make
to ignore -O3
when anything is passed in CFLAGS
(so specifying -mbmi2
or -mno-bmi2
caused the code to compile with -O0 (I guess?) and the code size exploded).
I'm not sure if this is intended, but I would expect that the behavior should be to override the -O3
only when -Osomething
was passed to CFLAGS.
Also when I was debugging this, I realized that the DYNAMIC_BMI2=0
I specified on the make command had no effect - it has to be passed with -D
(while other options has to be passed to make
.