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.