Issue with Clang on Windows and compiler-rt builtins

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

When clang-cl driver is used, it is even more troublesome because
clang-cl does not understand --rtlib flag! I have to type
for the link.exe. It is annoying to type something that long.

1. Add --rtlib flag to clang-cl driver.
2. Clang on Windows should automatically add #pragma comment(lib,
when it detects that a builtin feature that requires compiler-rt is
used, with or without --rtlib flag. #pragma comment(lib, *) is very

Issue 2 (related to

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_CXX_FLAGS=/DCRT_HAS_128BIT in CMake configuration step.

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]: compiler-rt/udivti3.c at master · llvm-mirror/compiler-rt · GitHub
[2]: compiler-rt/int_types.h at master · llvm-mirror/compiler-rt · GitHub


#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"));

Rong Jie

LLVM does not inline division or modulo for 128bit operands. Way too
much code.