[FFmpeg-devel] [PATCH] x86: cabac: Disable the inline asm on clang on windows on i386

Martin Storsjö martin at martin.st
Sun May 24 22:53:20 EEST 2020


On Sun, 24 May 2020, Carl Eugen Hoyos wrote:

> Am Sa., 23. Mai 2020 um 20:35 Uhr schrieb Martin Storsjö <martin at martin.st>:
>>
>> The cabac inline assembly is very brittle to assemble properly
>> on i386 windows with clang; libavcodec/hevc_cabac.c fails to build
>> in the default mode (which is -march=pentium4), it only works if
>> ffmpeg is configured with --cpu=i686 (translating to -march=i686),
>> and likewise, the inline assembly fails to assemble in
>> libavcodec/h264_cabac.c if building with optimizations disabled.
>>
>> Instead of trying to step around the problem (and end up bit by it
>> occasionally), just disable the inline assembly for this configuration.
>
> I think I cannot reproduce this issue, what may I miss?

That's a good question - how are you building? I can reproduce it both in 
mingw and msvc mode.

In mingw mode (with my llvm-mingw toolchains from 
https://github.com/mstorsjo/llvm-mingw, but any clang configured to target 
i386 mingw should do), I can reproduce it (in a cross compile setup) like 
this (tested with Clang 10.0 but any version should do, I remember seeing 
the issue long ago):

$ configure --cross-prefix=i686-w64-mingw32- --target-os=mingw32 
--arch=i686 --enable-gpl
$ make V=1
...
i686-w64-mingw32-gcc -I. -Isrc/ -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 
-D_LARGEFILE_SOURCE -U__STRICT_ANSI__ -D__USE_MINGW_ANSI_STDIO=1 
-D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -DHAVE_AV_CONFIG_H 
-DBUILDING_avcodec -std=c11 -fomit-frame-pointer -g 
-Wdeclaration-after-statement -Wall -Wdisabled-optimization 
-Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef 
-Wmissing-prototypes -Wno-pointer-to-int-cast -Wstrict-prototypes 
-Wempty-body -Wno-parentheses -Wno-switch -Wno-format-zero-length 
-Wno-pointer-sign -Wno-unused-const-variable -Wno-bool-operation 
-Wno-char-subscripts -O3 -fno-math-errno -fno-signed-zeros 
-Qunused-arguments -Werror=implicit-function-declaration 
-Werror=missing-prototypes -Werror=return-type  -MMD -MF 
libavcodec/hevc_cabac.d -MT libavcodec/hevc_cabac.o -c -o 
libavcodec/hevc_cabac.o src/libavcodec/hevc_cabac.c
warning: unknown warning option '-Wno-bool-operation'; did you mean 
'-Wno-bool-conversion'? [-Wunknown-warning-option]
src/libavcodec/hevc_cabac.c:37:21: warning: variable 'num_bins_in_se' is 
not needed and will not be emitted [-Wunneeded-internal-declaration]
static const int8_t num_bins_in_se[] = {
                     ^
In file included from src/libavcodec/hevc_cabac.c:27:
In file included from src/libavcodec/cabac_functions.h:46:
src/libavcodec/x86/cabac.h:193:9: error: inline assembly requires more 
registers than available
         BRANCHLESS_GET_CABAC("%0", "%q0", "(%4)", "%1", "%w1",
         ^


Same thing if I build in MSVC mode, by setting INCLUDE and LIB to point to 
the right MSVC folders, and configure like this:

$ configure --enable-gpl --arch=i686 --cc='clang -target i686-win32-msvc' 
--ld=lld-link --target-os=win32 --extra-ldflags='msvcrt.lib oldnames.lib' 
--enable-cross-compile --ar=llvm-ar --nm=llvm-nm --disable-stripping
$ make V=1
clang -target i686-win32-msvc -I. -Isrc/ -D_ISOC99_SOURCE 
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_USE_MATH_DEFINES 
-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS -D_WIN32_WINNT=0x0600 
-DHAVE_AV_CONFIG_H -DBUILDING_avcodec -std=c11 -fomit-frame-pointer -g 
-Wdeclaration-after-statement -Wall -Wdisabled-optimization 
-Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef 
-Wmissing-prototypes -Wno-pointer-to-int-cast -Wstrict-prototypes 
-Wempty-body -Wno-parentheses -Wno-switch -Wno-format-zero-length 
-Wno-pointer-sign -Wno-unused-const-variable -Wno-bool-operation 
-Wno-char-subscripts -O3 -fno-math-errno -fno-signed-zeros 
-Qunused-arguments -Werror=implicit-function-declaration 
-Werror=missing-prototypes -Werror=return-type  -MMD -MF 
libavcodec/hevc_cabac.d -MT libavcodec/hevc_cabac.o -c -o 
libavcodec/hevc_cabac.o src/libavcodec/hevc_cabac.c
src/libavcodec/hevc_cabac.c:37:21: warning: variable 'num_bins_in_se' is 
not needed and will not be emitted [-Wunneeded-internal-declaration]
static const int8_t num_bins_in_se[] = {
                     ^
In file included from src/libavcodec/hevc_cabac.c:27:
In file included from src/libavcodec/cabac_functions.h:46:
src/libavcodec/x86/cabac.h:193:9: error: inline assembly requires more 
registers than available
         BRANCHLESS_GET_CABAC("%0", "%q0", "(%4)", "%1", "%w1",
         ^

The same also seems to trigger in the same way if using the clang-cl 
frontend, e.g. configured like this:

configure --enable-gpl --arch=i686 --cc=clang-cl --ld=lld-link 
--target-os=win32 --toolchain=msvc --enable-cross-compile --ar=llvm-ar 
--nm=llvm-nm --disable-stripping --extra-cflags=-m32


In the first two cases, adding --cpu=i686 to the configure line, which 
converts into -march=i686 on the compile commands, makes the issue go 
away. For clang-cl, --cpu=i686 doesn't have any effect, so the issue 
doesn't easily go away there.

Now if configuring with --cpu=i686 --disable-optimizations, the same 
issues are back again, in both libavcodec/h264_cabac.o and 
libavcodec/hevc_cabac.o.

// Martin


More information about the ffmpeg-devel mailing list