Tracking Issue for `f16` and `f128` float types
traviscross opened this issue ยท 32 comments
This is a tracking issue for the RFC 3453 (rust-lang/rfcs#3453).
The feature gate for the issue is #![feature(f16_and_f128)].
From the RFC:
This RFC proposes adding new IEEE-compliant floating point types
f16andf128into the core language and standard library. We will provide a soft float implementation for all targets, and use hardware support where possible.
About tracking issues
Tracking issues are used to record the overall progress of implementation. They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Steps
- Implement the RFC (see the list of tasks here]
- Adjust documentation (see instructions on rustc-dev-guide)
- Stabilization PR (see instructions on rustc-dev-guide)
Unresolved questions
- Do any new target features need to be marked as "forbidden" since they affect ABI? The logic here looks like that may be the case.
Implementation history
- Add basic support stubs to IR and backend interfaces: #121728
- Add AST support and intrinsics: #121841 (comment)
- Connect the frontend, add the feature gate: #121926
- Add the most basic traits that
rustcmore or less expects for primitives #123085 - Finish support in rustdoc #123581
- Add library support.
Some parts are blocked on const eval, compiler builtins updates, and LLVM lowering bugs.hooray, this part is done! - Add needed functions to compiler-builtins. Unfortunately this one will block almost everything else on the list.
- Figure out parsing and printing
- Migrate the tester to accept more types #127510
- Add
f16, which should be straightforward #127013 - Figure out
f128which will not be straightforward. Our current implementations are prettyu64-dependent so they can't fit af128mantissa. We could make them generic but probably want to instead use an implementation that is slower but better for size.
- Update const eval
- Figure out mangling
#122106#123816 -
Ensure known demanglers get updated or at least have issues for adding the new typesunneeded with the forward-compatible demangling - Add SIMD operations that can make use of these types #125440
- Enable assembly registers where it makes sense #125398
- Make sure the GCC and Clif backends handle these types gracefully
- rust-lang/rustc_codegen_gcc#461 (merged upstream, waiting on sync)
- rust-lang/rustc_codegen_cranelift#1461
- Migrate float intrinsics to have a fallback (changes from #93145)
- Make sure all relevant
unimplementeds andFIXMEs are removed from tools that need library support - Make use of new diagnostic attributes, e.g.
f16_nan - Figure out ABI & platform-specific problems (thanks @beetrees for just about all of these)
- f16 ABI bugs in compiler-rt #123885
- 32-bit ABI bugs from LLVM llvm/llvm-project#80195 (comment)
- f16 miscompilations from LLVM (affects T2 and T3 targets) llvm/llvm-project#97975 llvm/llvm-project#97981
- f16 abs and neg quieten signalling NaNs on emulated targets llvm/llvm-project#104915 (comment)
- #131819
- Tier 1 MinGW incompatibilities from GCC https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054
- Tier2 PowerPC BE precision issues #125109
- Tier2 Power9 possible ABI issues #125102
- Tier2 PowerPC LE
f128 as f16casting bug llvm/llvm-project#92866 - Tier 2 PowerPC sometimes uses the wrong symbol names llvm/llvm-project#98126
- Tier 2 Loongarch failure to select llvm/llvm-project#93894 (fixed upstream)
- Tier 2 arm64ec does not support these types llvm/llvm-project#94434
- Tier 2 s390x-unknown-linux-gnu doesn't support f16: llvm/llvm-project#50374
- Tier 2 wasm32 correctness bug llvm/llvm-project#96437
- Tier 2 nvptx64-nvidia-cuda doesn't support f128: llvm/llvm-project#95471
- Tier 3 mips LLVM crashes with
f128llvm/llvm-project#96432 - Tier 3 sparc-unknown-linux-gnu doesn't support passing f128 directly (error message SPARCv8 does not handle f128 in calls; pass indirectly): llvm/llvm-project#41838
- Tier 3
powerpc64-ibm-aixdoesn't currently supportf128arguments: llvm/llvm-project#101545
- Other misc miscompilations or bugs
- LLVM does
fma.f16incorrectly llvm/llvm-project#98389 -
powi.f16constant folding returns incorrect values llvm/llvm-project#98665
- LLVM does
- Eventually, stabilization
Note that unimplemented!("f16_f128") and // FIXME(f16_f128) is being used where relevant, to make the todo list easily greppable.
Nice to have changes:
- Better debuginfo for MSVC #121837
-
f16: #127001 -
f128
-
- A bit of ecosystem support
- Rust-analyzer rust-lang/rust-analyzer#17451
- Bytemuck Lokathor/bytemuck#250
- Zerocopy google/zerocopy#2042
- Serde
- num
- rug https://gitlab.com/tspiteri/rug/-/issues/68
- syntax highlighters
@rustbot labels +T-lang
@rustbot labels +B-rfc-approved
@rustbot claim
@rustbot release-assignment
@rustbot prioritize
@rustbot ping types
@rustbot label: +T-compiler
This is a tracking issue and doesn't need prioritization.
A blocking issue should be added: ensure C compatibility with ABI-cafe or similar
Implementation steps (could somebody link this in the top post?):
(massive todo list moved to the top post)
@rustbot claim
@tgross35 we (rizinorg) have merged the changes on our demangling library. i have added also some tests https://github.com/rizinorg/rz-libdemangle/blob/main/test/test_rust.c#L75-L78
@tgross35 we (rizinorg) have merged the changes on our demangling library. i have added also some tests https://github.com/rizinorg/rz-libdemangle/blob/main/test/test_rust.c#L75-L78
That was super fast :) the update is much appreciated.
Note that the mangling isn't actually finalized but does seem reasonably likely to merge as-is #122106
i don't think that will be a big issue. i can always fix this once is merged if it ever changes.
@tgross35 i will. i read about the decision yesterday, so for me is just a couple of lines that needs to be removed. thank you for your wonderful work!
arm64ec-pc-windows-msvc can't compile functions that pass or return f16 or f128 due to llvm/llvm-project#94434.
More LLVM bugs:
- Tier 2
s390x-unknown-linux-gnudoesn't supportf16: llvm/llvm-project#50374 - Tier 2
nvptx64-nvidia-cudadoesn't supportf128: llvm/llvm-project#95471 - Tier 3
sparc-unknown-linux-gnudoesn't support passingf128directly (error messageSPARCv8 does not handle f128 in calls; pass indirectly): llvm/llvm-project#41838
64-bit MIPS targets (all tier 3) have a bug involving f128 that prevents compilation of compiler-builtins in debug mode without the no-f16-f128 feature: llvm/llvm-project#96432
wasm32 (tier 2) has f16 bugs with failing to round in-between operations (llvm/llvm-project#96437) and quietening signalling NaNs in some situations when passing to and returning from a function (llvm/llvm-project#96438).
It seems the LLVM f16 excess precision and ABI-handling bugs aren't limited to WASM:
The list of affected LLVM backends is included in each issue: both affect tier 2 and tier 3 Rust targets.
The test suite currently fails on s390x in the following doctests:
library/core/src/num/f16.rs - f16::f16::is_sign_negative (line 377)
library/core/src/num/f16.rs - f16::f16::is_sign_positive (line 354)
library/core/src/num/f16.rs - f16::f16::to_be_bytes (line 695)
library/core/src/num/f16.rs - f16::f16::to_le_bytes (line 716)
library/core/src/num/f16.rs - f16::f16::to_ne_bytes (line 743)
due to
rustc-LLVM ERROR: Cannot select: 0x3ffcc0737a0: i32 = fp_to_fp16 0x3ffcc072fc0
(which is llvm/llvm-project#50374)
After #127235 most doctests are already restricted to x64_64 (or aarch64), but these few listed above remain active on all Linux platforms. Could those also be restricted for now (until the s390x LLVM back-end is fixed) so that the test suite passes again? Thanks!
LLVM lowers f16 FMA incorrectly on targets without native f16 FMA support (so this will affect most targets including all tier 1 targets): llvm/llvm-project#98389
It appears that today f128 doesn't trigger the incomplete_features lint: https://play.rust-lang.org/?version=nightly&mode=release&edition=2021&gist=9d8a3698d5d506fc960bde270e9a1a54
It might be a good idea to do that for now, to avoid people making threads like https://users.rust-lang.org/t/display-for-f128/114405?u=scottmcm
Tier 3 powerpc64-ibm-aix doesn't currently support f128 arguments: llvm/llvm-project#101545
llvm/llvm-project#104915: f16 abs and neg quieten signalling NaNs on targets where f16 is not natively supported.
Hurry up. I can't wait
Warning: div_euclid and rem_euclid is buggy. I'm not sure whether they need be marked as unsafe, since calculate div/rem with floating types are strongly discouraged.
#![feature(f16, f128)]
fn main() {
let a = 1.2f16;
let b = 1.1f32;
let c = 1.1f64;
let d = 1.1f128;
println!(
"{} {} {} {}",
(12f16).div_euclid(a) as f64,
(11f32).div_euclid(b),
(11f64).div_euclid(c),
(11f128).div_euclid(d) as f64
);
println!(
"{} {} {} {}",
(12f16).rem_euclid(a) as f64,
(11f32).rem_euclid(b),
(11f64).rem_euclid(c),
(11f128).rem_euclid(d) as f64
);
}
// 10 10 10 10
// 1.1982421875 1.0999998 1.0999999999999992 1.1@Neutron3529: If you could, the thing to do would be to file a separate issue for that if there isn't one already. Reference this tracking issue in that new issue.