zstd icon indicating copy to clipboard operation
zstd copied to clipboard

Weird code size when -mbmi2 or -mno-bmi2 is specified

Open Dom324 opened this issue 1 year ago • 2 comments

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

Dom324 avatar Oct 21 '23 22:10 Dom324

Could bmi2 also enable avx2 transparently ?

Cyan4973 avatar Oct 22 '23 00:10 Cyan4973

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.

Dom324 avatar Oct 22 '23 13:10 Dom324