[cfe-dev] Issue with Clang on Windows and compiler-rt builtins

Rong Jie Loo via cfe-dev cfe-dev at lists.llvm.org
Sun Jan 7 01:47:14 PST 2018


Hi Clang devs,

I have some issues with Clang on Windows. See the bottom of this
message for the reduced test case.

Issue 1:

When __builtin_cpu_supports is used, Clang will generate reference to
a symbol named __cpu_model. For Linux and Mac, linker can get this
symbol from libgcc_s.a and/or libgcc.a, but since MSVC does not have
them, linker error is produced.

This can be solved by linking to compiler-rt (specifically
clang_rt.builtins-x86_64.lib). For clang and clang++ driver, I have to
manually add --rtlib=compiler-rt flag so that the clang drivers will
pass the builtins lib to link.exe linker. Slightly troublesome as
compiler knows better than user about whether compiler-rt is needed or
not.

When clang-cl driver is used, it is even more troublesome because
clang-cl does not understand --rtlib flag! I have to type
"/defaultlib:<llvm-root>/lib/clang/6.0.0/lib/windows/clang_rt.builtins-x86_64.lib"
for the link.exe. It is annoying to type something that long.

Suggestions:
1. Add --rtlib flag to clang-cl driver.
2. Clang on Windows should automatically add #pragma comment(lib,
"<llvm-root>/lib/clang/6.0.0/lib/windows/clang_rt.builtins-x86_64.lib")
when it detects that a builtin feature that requires compiler-rt is
used, with or without --rtlib flag. #pragma comment(lib, *) is very
useful.

Issue 2 (related to https://bugs.llvm.org/show_bug.cgi?id=25305):

When __int128 operations are used, Clang on Windows generate calls to
compiler-rt builtins (__udivti3 etc.) instead of generating inline
optimized assembly directly.

However, compiler-rt builtins related to __int128 are guarded by
CRT_HAS_128BIT (see [1]), but CRT_HAS_128BIT is not defined for
Windows (see [2])! Yet another linker error. My workaround is to use
-DCMAKE_C_FLAGS=/DCRT_HAS_128BIT and
-DCMAKE_CXX_FLAGS=/DCRT_HAS_128BIT in CMake configuration step.

Suggestions:
1. Define CRT_HAS_128BIT for Windows (short-term fix).
2. Clang on Windows should generate inline optimized assembly for
__int128 operations, avoiding function calls completely (as far as I
know this is what Clang on Linux/Mac does already).

CC-ing Reid Kleckner for more advise.

[1]: https://github.com/llvm-mirror/compiler-rt/blob/master/lib/builtins/udivti3.c#L17
[2]: https://github.com/llvm-mirror/compiler-rt/blob/master/lib/builtins/int_types.h#L63

Code:

#include <cstdio>
#include <cstdint>

extern "C" unsigned __int128 __attribute__((noinline)) f(unsigned
__int128 a, unsigned __int128 b) {
  return a / b;
}

int main() {
  __int128 x = f(23, 12);
  int64_t* p = reinterpret_cast<int64_t*>(&x);
  printf("%lld %lld\n", p[0], p[1]);
  printf("%d\n", __builtin_cpu_supports("sse4.2"));
}

Thanks,
Rong Jie



More information about the cfe-dev mailing list