Skip to content

c(x86-64 SysV): converting x87 long double to _Float16 is refused ("does not support this runtime conversion to binary16") #1731

Description

@davidgmbb

Observed

_Float16 h(long double a) { return a; }
$ build/Release/ide cc -c -target x86_64-linux h.c
cc: error: h.c:1:35: in function 'h': C IR lowering does not support this runtime conversion to binary16

Clang 18 (--target=x86_64-linux-gnu) compiles it to one call to __truncxfhf2, which libgcc has provided since GCC 12. The refusal is deliberate: the binary16 arm of c_ir_emit_cast in src/buster/lib/compiler/frontend/c/c_gen.c refuses wider-than-64-bit sources, because routing them through __truncsfhf2 would double-round. The parser mirrors it in c_parse_scalar_conversion_message (c_parse.c). No direct x87 entry point is wired in. Complex long double → _Float16 goes through the same path.

Expected

Lower (_Float16)x87_value to __truncxfhf2(long double) with the x87 operand in its usual memory/stack position, as Clang does. Also relax the parser mirror, which #1720 made target-aware for the AAPCS64 binary128 case (__trunctfhf2). Widening _Float16 → x87 should be checked at the same time; it is exact through binary32.

Details

Done when

The function above compiles in all x86-64 SysV allocators with zero fallback, and a fixture checks the rounded binary16 bits against Clang for ties, subnormals, overflow to infinity and NaN.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions