ned14 / quickcpplib

Eliminate all the tedious hassle when making state-of-the-art C++ 14 - 23 libraries!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Mem flush intrinsics on clang-cl

BurningEnlightenment opened this issue · comments

#ifndef _MSC_VER
static const auto __cpuidex = [](int *cpuInfo, int func1, int func2) { __asm__ __volatile__("cpuid\n\t" : "=a"(cpuInfo[0]), "=b"(cpuInfo[1]), "=c"(cpuInfo[2]), "=d"(cpuInfo[3]) : "a"(func1), "c"(func2)); }; // NOLINT
// static constexpr auto _mm_clwb = [](const void *addr) { __asm__ __volatile__("clwb (%0)\n\t" : : "r"(addr)); }; // NOLINT
static const auto _mm_clwb = [](const void *addr) { __asm__ __volatile__(".byte 0x66, 0x0f, 0xae, 0x30\n\t" : : "a"(addr)); }; // NOLINT
static const auto _mm_clflushopt = [](const void *addr) { __asm__ __volatile__("clflushopt (%0)\n\t" : : "r"(addr)); }; // NOLINT
static const auto _mm_clflush = [](const void *addr) { __asm__ __volatile__("clflush (%0)\n\t" : : "r"(addr)); }; // NOLINT
static const auto _mm_sfence = []() { __asm__ __volatile__("sfence\n\t"); }; // NOLINT
#endif

clang-cl doesn't provide these, therefore the preprocessor guard should be

#if !defined(_MSC_VER) || defined(__clang__)

Any clang I've used likes those just fine.

Which clang are you on?

C:\Program Files\LLVM\bin> .\clang-cl.exe --version
clang version 9.0.0 (tags/RELEASE_900/final)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin

It's the official clang 9.0.0 release obtained from their download page. However, note that I'm using the clang-*cl* driver which targets the msvc ABI.

Looks like this problem is peculiar to the msvc targeting clang. I'm very very sure that Linux clang "just works" on this, except for very old versions of clang for which LLFIO wouldn't compile anyway.

I'll see if I can think of some workaround which will work for you here and get back to you.

Just to make sure we don't talk past each other:

My understanding was that the __cpuidex, _mm_clwb, etc. intrinsics are only provided by MSVC, hence the #ifndef _MSC_VER excludes the shims when MSVC compiles the code. If clang-cl compiles the code it doesn't provide the intrinsics, but also defines _MSC_VER. I.e. the shims are excluded even though they are needed.

Which is why I think #if !defined(_MSC_VER) || defined(__clang__) should fix the issue without affecting anything outside MSVC and clang-cl on windows.

Did I miss something?

Which is why I think #if !defined(_MSC_VER) || defined(clang) should fix the issue without affecting anything outside MSVC and clang-cl on windows.

Did I miss something?

Nothing that you could be aware of. Those intrinsics are present on the clang with the MSVC backend if I remember rightly, so I'm going to need some preprocessor logic which includes clang-targeting-msvc but excludes clang-with-msvc-backend. Something based on defined(__c2__) I would assume.

clang with the MSVC backend

Indeed, I forgot that this... thing still exists 😅

Should be fixed. To use, delete the quickcpplib inside your build directory, and rerun cmake.