Page MenuHomePhabricator

[libcxx] Provide __int128_t builtins needed for filesystem on MSVC
Needs ReviewPublic

Authored by mstorsjo on Fri, Nov 13, 4:32 AM.

Details

Reviewers
amccarth
thakis
Group Reviewers
Restricted Project
Summary

When building with clang-cl targeting MSVC, the __int128_t type is available, but the runtime helpers (normally provided by libgcc or compiler_rt builtins) aren't available; bundle them within libc++ in those cases. (The same is already done for one function that is missing in libgcc but present in compiler_rt.)

This is an alternative to D91139 (which just disables the use of int128_t for MSVC targets). Either of these has to be picked before settling down the ABI of libc++ filesystem on MSVC targets. This one on the other hand hardcodes the clang-specific int128_t into the ABI for MSVC targets.

(For MinGW targets, none of this is an issue as libgcc and/or compiler_rt are available.)

Diff Detail

Event Timeline

mstorsjo created this revision.Fri, Nov 13, 4:32 AM
Herald added a project: Restricted Project. · View Herald TranscriptFri, Nov 13, 4:32 AM
Herald added 1 blocking reviewer(s): Restricted Project. · View Herald Transcript
Herald added a subscriber: mgorny. · View Herald Transcript

Hrm, this seems like a fix at the wrong layer to me.

Since int128_t creates compiler_rt calls, it'd seem reasonable if we made uint128_t error out when targeting windows in the compiler, or if we changed codegen to call _mul128() on windows, or some such. This change here would mean that making such a change in clang would break libcxx, which seems a bit unfortunate.

Maybe we should just teach clang to use _mul128() when targeting windows?

nvm, _mul128 multiplies two 64-bit numbers. but the point that this seems like a libc++-level workaround around a clang bug still stands.

Since int128_t creates compiler_rt calls, it'd seem reasonable if we made uint128_t error out when targeting windows in the compiler

So you'd suggest going with D91139 then instead?

I'd try to do some fix on the clang side. For example, don't define SIZEOF_INT128T when targeting windows triples (and don't have int128_t support in general), or make it a compile-time option, for people who want to link against compiler-rt vs those who don't, or make it not depend on compiler-rt but add the bit above as intrinsic when targeting windows.

I'd try to do some fix on the clang side. For example, don't define SIZEOF_INT128T when targeting windows triples (and don't have int128_t support in general), or make it a compile-time option, for people who want to link against compiler-rt vs those who don't, or make it not depend on compiler-rt but add the bit above as intrinsic when targeting windows.

The distinction between "has compiler-rt/libgcc or not" already exists, as the distinction between msvc and mingw targets.

As for not defining __SIZEOF_INT128T__ (i.e. disabling support for __int128_t) when targeting msvc, it's simple to do, but it breaks half a dozen clang tests at least, including CodeGenCXX/mangle-ms-templates.cpp, where it seems pretty much intentional that the int128 type is supported for x86_64 MSVC targets.

As for making int128 divisions expand inline to code instead of emitting a libcall, for msvc targets, I guess it would be doable with some amount of effort, but the division expansion code in llvm currently only supports 64 bit divisions (but maybe it'd be straightforward to extend it to 128 bit?).

In any case, I can leave out this and D91139 for now; my main target for std::filesystem is for mingw targets, but I thought I'd make it work for MSVC targets at the same time, but that'd require a MSVC target code owner to drive a path forward.