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.
Observed
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 ofc_ir_emit_castinsrc/buster/lib/compiler/frontend/c/c_gen.crefuses wider-than-64-bit sources, because routing them through__truncsfhf2would double-round. The parser mirrors it inc_parse_scalar_conversion_message(c_parse.c). No direct x87 entry point is wired in. Complexlong double→_Float16goes through the same path.Expected
Lower
(_Float16)x87_valueto__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
c3f93e8(branch of aarch64: lower binary128 long double through the compiler runtime #1720, which does not change the x87 path); Linux x86-64.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.