llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.92k stars 11.52k forks source link

Compiler-rt missing __float128 builtins for x86_64 #38724

Open m-gupta opened 5 years ago

m-gupta commented 5 years ago
Bugzilla Link 39376
Version unspecified
OS Windows NT
CC @DoDoENT,@efriedma-quic,@jsonn,@lalozano,@m-gupta,@pabristow,@stephenhines

Extended Description

Chrome OS bug: https://bugs.chromium.org/p/chromium/issues/detail?id=843822

With glibc 2.27, clang cannot compile a static binary with compiler-rt since compiler-rt does not have support for long double builtins for x86_64.

With glibc 2.27 cat a.c

include "stdio.h"

int main() { printf("hello.\n"); }

clang -static a.c -rtlib=compiler-rt /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/../../../../lib64/libc.a(printf_fp.o): In function __printf_fp_l': (.text+0x5ea): undefined reference tounordtf2' /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.x/../../../../lib64/libc.a(printf_fphex.o): In function `printf_fphex': (.text+0x9a): undefined reference to `__unordtf2'

The following patch is enough to add the builtins to compiler-rt but not sure of the correctness or any other implications. Interesting thing to note is that LDBL_MANT_DIG is 64 so the check LDBL_MANT_DIG == 113 failed on x86_64/Linux.

diff --git a/lib/builtins/CMakeLists.txt b/lib/builtins/CMakeLists.txt index 82332967b..c49d9af00 100644 --- a/lib/builtins/CMakeLists.txt +++ b/lib/builtins/CMakeLists.txt @@ -232,6 +232,7 @@ set(x86_ARCH_SOURCES

if (NOT MSVC) set(x86_64_SOURCES

DoDoENT commented 2 years ago

I'm using LLVM 13

DoDoENT commented 2 years ago

I can also reproduce this with glibc 2.26 on Amazon Linux 2 using this docker image.

The Dockerfile for that image can be found here.

d614a738-40cc-4650-8cce-651e101d7d97 commented 5 years ago

Thanks.

What is machine mode 'TC'?

It's a complex 128-bit float (i.e. a pair of 128-bit floats).

Is curious as I am not knowinly using complex, but perhaps it is in the internals of Boost.Multiprecision.

As suggested I have posted a new 'bug'.

llvm/llvm-bugzilla-archive#40879

__float_128 clang-cl on Windows 10 x64 using Mingw64 / GCC 8.1 to enable 128-bit float Boost.Multiprecision and Boost.Math fails to compile

efriedma-quic commented 5 years ago

Any suggestions on how this might be made to work?

Please file a new bug. The compile-time error is not really the same issue. (IIRC we restrict the targets where 128-bit floats are supported for gcc compatibility; not sure what the current state is.)

What is machine mode 'TC'?

It's a complex 128-bit float (i.e. a pair of 128-bit floats).

d614a738-40cc-4650-8cce-651e101d7d97 commented 5 years ago

Having finally got clang-cl to work on Windows 10 using Mingw64 / GCC 8.1,

I was hoping to be able to run Boost.Multiprecision and Boost.Math examples that use float128 using GCC's quadmath.h and the library libquadmath.dll. These examples all work as expected for GCC.

When I make quadmath.h visible via an include, or copying the file into Clang's include tree, I get this disappointing message

C:\LLVM\clang-800\LLVM\lib\clang\8.0.0\include\quadmath.h(33): error: unsupported machine mode 'TC' C:\LLVM\clang-800\LLVM\lib\clang\8.0.0\include\quadmath.h(47): error: __float128 is not supported on this target

Any suggestions on how this might be made to work?

What is machine mode 'TC'?

It would provide full Boost multiprecision portability on the msvc, gcc and clang platforms.

Thank you.

m-gupta commented 5 years ago

afaik, that change is not complete or correct for float128 on x86_64 since it was likely causing fp80 functions to be (mis)compiled as f128 but I haven't investigated since then.

llvmbot commented 5 years ago

With the change above, what functions would still be missing?

m-gupta commented 5 years ago

Thanks Eli,

I have corrected the bug title. I want to work on adding the missing pieces but will need to find some time for it.

efriedma-quic commented 5 years ago

Compiler-rt is using the long double type for the builtins under quad precision (for all architectures). Maybe __float128 should have been used instead?

That's the right approach. (compiler-rt was written before __float128 existed, so "should have been used" isn't really right, but you get the idea.)

m-gupta commented 5 years ago

Compiler-rt is using the long double type for the builtins under quad precision (for all architectures). Maybe __float128 should have been used instead?

For x86, My understanding is generally compiler converts uses of long double to fp80 instructions so the uses are often not emitted as call to builtins.

lib/builtins/fp_lib.h

elif defined QUAD_PRECISION

if LDBL_MANT_DIG == 113

define CRT_LDBL_128BIT

typedef uint128_t rep_t; typedef int128_t srep_t; typedef long double fp_t;

define REP_C (__uint128_t)

jsonn commented 5 years ago

Aren't you confusing long double (aka 80bit Intel extended precision) with IEEE754 quad precision?

brad0 commented 9 months ago

I believe this https://github.com/llvm/llvm-project/commit/d2ce3e9621411f3391def327f89e3a650918989f should fix the issue you're experiencing.