[cfe-dev] clang-cl's <intrin.h>, _tzcnt_u32, and compatibility with MSVC's <intrin.h>

Nathan Froyd via cfe-dev cfe-dev at lists.llvm.org
Thu Sep 29 10:50:37 PDT 2016


[While I filed this as https://llvm.org/bugs/show_bug.cgi?id=30506,
Paul Robinson suggested in the bug that it might be worth bringing to
cfe-dev for wider discussion.]

Firefox's copy of FFmpeg includes <intrin.h> on MSVC:

https://dxr.mozilla.org/mozilla-central/source/media/ffvpx/libavutil/x86/intmath.h#26

and MSVC's <intrin.h> (after including several other headers) declares
_tzcnt_u32.  clang-cl declares _tzcnt_u32 in <bmiintrin.h>, but
<bmiintrin.h> is only included from <intrin.h> if an appropriate
target CPU is detected:

https://github.com/llvm-mirror/clang/blob/master/lib/Headers/immintrin.h#L82

even though _tzcnt_u32 (or rather, its underlying implementation
function, __tzcnt_u32) is explicitly declared to be available
everywhere:

https://github.com/llvm-mirror/clang/blob/master/lib/Headers/bmiintrin.h#L284

The net result is that Firefox's copy of FFmpeg doesn't compile with
clang-cl because of this issue.  Upstream has the same code, so I
assume the same is true there:

https://github.com/FFmpeg/FFmpeg/blob/master/libavutil/x86/intmath.h#L26

AFAICT, this behavior was changed by only including <bmiitrin.h> if
__BMI__ is defined in:

http://reviews.llvm.org/D20291

with the desirable goal of reducing compile time.  But this change
also broke things like _tzcnt_u32 being available.

What is the right thing to do here?  Should <bmiintrin.h> be
unconditionally included, or should something else be done?

Thanks,
-Nathan


More information about the cfe-dev mailing list