This is an archive of the discontinued LLVM Phabricator instance.

[compiler-rt][X86] add half <-> x86_fp80 conversion builtins
Needs ReviewPublic

Authored by t.p.northover on Dec 12 2022, 7:09 AM.
This revision needs review, but there are no reviewers specified.

Details

Reviewers
None
Summary

With the recently(ish) added support for _Float16, LLVM is now emitting libcalls to convert to and from long double (particularly important for the trunc to avoid double-rounding). Latest GCC already seems to include these in libgcc, but compiler-rt hasn't up to now.

It's a bit messy in the implementation files since x86_fp80 has an explicit digit with the integer part of the significand unlike the other types that have an implicit 1.abcde... except for denormals. I handled this by converting to an imaginary "normal" 80-bit float when needed.

The extend tests were derived from half -> float -> x86_fp80 two-step conversion, the truncate tests didn't need changing from the regular float versions since the _Float16 representation is the same in both cases.

Diff Detail

Event Timeline

t.p.northover created this revision.Dec 12 2022, 7:09 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 12 2022, 7:09 AM
t.p.northover requested review of this revision.Dec 12 2022, 7:09 AM
Herald added a project: Restricted Project. · View Herald TranscriptDec 12 2022, 7:09 AM
Herald added a subscriber: Restricted Project. · View Herald Transcript

Remove COMPILER_RT_HAS_FLOAT16 check. It's actually a soft/float ABI check rather than whether to support the type entirely (at least for conversions) so it meant the new functions didn't get built on Darwin (which is still soft-float for _Float16 compiler-rt calls for historic reasons).

Tests weren't running on Darwin properly for some reason so things were a bit broken there.

  • __truncxfhf2 had wrong (hard-float) ABI because it hardcoded _Float16 as the return type.
  • The tests were copying 16 bytes of a 10-byte long double because sizeof(long double) is weird.