64-bit long double for x86-64?
It seems that llvm-mingw used to define the x86-64 long double as 80-bit for gcc compatibility, which made many UCRT math functions unusable. But nowadays llvm-mingw is not gcc-compatible anyway, so would it be possible to add a 64-bit variant of long double for x86-64 to improve performance and MSVC compatibility? This seems to require a modification on the MinGW CRT side, and -mlong-double-64 won't work.
But nowadays llvm-mingw is not gcc-compatible anyway
Can you quantify what you refer to here? llvm-mingw is generally ABI compatible with GCC. C++ code that refers to the standard C++ library isn't compatible across C++ libraries of course though. And object files/static libraries built for UCRT isn't generally safe to mix with similar ones built for msvcrt.dll - but that's not an issue specific to llvm-mingw or Clang vs GCC.
so would it be possible to add a 64-bit variant of long double for x86-64 to improve performance and MSVC compatibility? This seems to require a modification on the MinGW CRT side
Yes, this would require quite large modifications there.
If you want the performance of 64 bit doubles, use double, not long double.
If you want the performance of 64 bit doubles, use
double, notlong double.
To provide more context on this; e.g. on aarch64 linux, long double is actually 128 bit softfloats. (For aarch64 mingw, we did match MSVC and just went with plain 64 bit doubles - matching what MSVC does, does have its advantages of course. But at this point, changing it for x86 would be a large amount of work and lots of conditionals in mingw-w64, especially when the x87 long doubles have to be kept for GCC.)
Can you quantify what you refer to here? llvm-mingw is generally ABI compatible with GCC. C++ code that refers to the standard C++ library isn't compatible across C++ libraries of course though. And object files/static libraries built for UCRT isn't generally safe to mix with similar ones built for msvcrt.dll - but that's not an issue specific to llvm-mingw or Clang vs GCC.
The main incompatibilities are toolchain runtime: compiler-rt, libc++, libunwind, but there are still some incompatibilities besides that which are not related to runtime: CFGuard, AVX512, TLS, LTO. Anyway, apart from msys2 mingw64/ucrt64 env, there is no other llvm-mingw distribution specifically configured to be compatible with GCC.
If you want the performance of 64 bit doubles, use
double, notlong double.
I'm sorry, but I'm only using llvm-mingw to build software, so it's not something I can decide.
For some software, VTune says a lot of CPU time is wasted on MinGW's slow math functions, and since its implementation is inline x87, even -O3 -march=native doesn't help, which creates an unbridgeable performance gap compared to MSVC/Clang-CL builds. After some searching, I found that the 80-bit long double was the cause of the inability to use the UCRT implementation. I'm just hoping to get rid of the 80-bit long double to solve this problem, just like aarch64.
Can you quantify what you refer to here? llvm-mingw is generally ABI compatible with GCC. C++ code that refers to the standard C++ library isn't compatible across C++ libraries of course though. And object files/static libraries built for UCRT isn't generally safe to mix with similar ones built for msvcrt.dll - but that's not an issue specific to llvm-mingw or Clang vs GCC.
The main incompatibilities are toolchain runtime: compiler-rt, libc++, libunwind
Compiler-rt and libunwind are only implementation differences, and they are ABI compatible with libgcc.
but there are still some incompatibilities besides that which are not related to runtime: CFGuard, AVX512, TLS, LTO.
TLS is indeed a bit of an issue, but there are actually things happening in GCC to move towards native TLS here.
The rest also isn't about ABI differences, but just differing sets of features or how to invoke them - not ABI level incompatibilities.
In any case - your wish is noted.
@Andarwinux: Currently I'm working on this: creating patches for mingw-w64 to be compatible with -mlong-double-64. However, I only have a low rate of progress at the time.
The disadvantge of this approach is: such patches will most likely never be accepted upstream and to keep patches like this healthy in the long term is quite a bit of effort.
@Andarwinux: Currently I'm working on this: creating patches for mingw-w64 to be compatible with
-mlong-double-64. However, I only have a low rate of progress at the time. The disadvantge of this approach is: such patches will most likely never be accepted upstream and to keep patches like this healthy in the long term is quite a bit of effort.
Good to know! It would be nice to have it as an experimental option disabled by default. I think @cjacek might be interested in your work, which might also help with arm64ec.
Yes, I hope we can have support for that upstream.
The latest MinGW seems to be working with -mlong-double-64.
The latest MinGW seems to be working with -mlong-double-64.
The things that are merged so far is not everything you need for working -mlong-double-64, a couple other things are needed as well.
There are two commits left in https://github.com/mstorsjo/mingw-w64/compare/master...long-double-64 which are needed (although with UCRT you don't need the more messy/hacky of those two).
But in addition to having those commits in place, if you want to use -mlong-double-64, you do need to rebuild the mingw-w64-crt with that set. Just setting it on your user code isn't entirely enough.
In my testing, I'm adding that option to the i686/x86_64 clang config files, https://github.com/mstorsjo/mingw-w64/commit/65c8474b4bb92d7d8713d39324d6364e533be064, and then rebuilding the mingw-w64-crt on top of that. (To be complete, you may also need to rebuild all other runtimes on top, i.e. libcxx and other things.)
The latest MinGW seems to be working with -mlong-double-64.
The things that are merged so far is not everything you need for working
-mlong-double-64, a couple other things are needed as well.There are two commits left in mstorsjo/[email protected] which are needed (although with UCRT you don't need the more messy/hacky of those two).
But in addition to having those commits in place, if you want to use
-mlong-double-64, you do need to rebuild the mingw-w64-crt with that set. Just setting it on your user code isn't entirely enough.In my testing, I'm adding that option to the i686/x86_64 clang config files, mstorsjo/mingw-w64@65c8474, and then rebuilding the mingw-w64-crt on top of that. (To be complete, you may also need to rebuild all other runtimes on top, i.e. libcxx and other things.)
Thanks! Yes, since I'm targeting an x86-64-v3 toolchain, I've always just considered UCRT and built the whole toolchain from scratch.
Thanks! Yes, since I'm targeting an x86-64-v3 toolchain, I've always just considered UCRT and built the whole toolchain from scratch.
Right, ok. As long as you include the -mlong-double-64 (e.g. by adding it to the .cfg files) before/while building mingw-w64-crt and the runtimes, you should be quite nearly there, only https://github.com/mstorsjo/mingw-w64/commit/c471cef0d7e4365c01ac74b9afb1310fd4b6ec20 still missing.
Thanks! Yes, since I'm targeting an x86-64-v3 toolchain, I've always just considered UCRT and built the whole toolchain from scratch.
Right, ok. As long as you include the
-mlong-double-64(e.g. by adding it to the.cfgfiles) before/while building mingw-w64-crt and the runtimes, you should be quite nearly there, only mstorsjo/mingw-w64@c471cef still missing.
If I understand correctly, for UCRT+LD64 case, MINGW ANSI STDIO is no longer necessary. Can we make __USE_MINGW_ANSI_STDIO a no-op in MinGW when _UCRT is defined and LDBL_MANT_DIG == DBL_MANT_DIG? This would prevent legacy programs from still defined __USE_MINGW_ANSI_STDIO.