Add mul_add_relaxed methods for floating-point types#151793
Add mul_add_relaxed methods for floating-point types#151793landsharkiest wants to merge 1 commit into
Conversation
|
rustbot has assigned @Mark-Simulacrum. Use |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@landsharkiest friendly reminder that this PR is waiting for you to react to the reviewer's feedback and to fix CI. :) |
|
Another thing, please update the doc comment of the intrinsics to point to the public methods, like here rust/library/core/src/intrinsics/mod.rs Lines 1459 to 1480 in a6050b7 We use the prasing of "stabilized" here even if the methods are not actually stable. |
0ca5122 to
174bea7
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
Sorry got caught up in school and job searching, will finally put this away! :) |
This comment has been minimized.
This comment has been minimized.
174bea7 to
67e0947
Compare
|
@rustbot ready |
|
Reminder, once the PR becomes ready for a review, use |
| /// ``` | ||
| /// #![feature(f128)] | ||
| /// #![feature(float_mul_add_relaxed)] | ||
| /// # #[cfg(any(miri, target_has_reliable_f128_math))] { // Miri uses softfloats, always works |
There was a problem hiding this comment.
Hm, this seems suspicious.
I suspect this might be Claude-generated though, I don't see the same pattern repeated elsewhere (e.g., in f16 just below). @landsharkiest, is there some difference between f16/f128 miri behavior?
If this is needed I'll poke Miri folks to figure out how we can avoid it being needed, in the meantime I would drop miri from the cfg here. The right way to express this implication is for Miri to set target_has_reliable (if it's reliable) IMO.
There was a problem hiding this comment.
target_has_reliable_f128 is always set in Miri, but target_has_reliable_f128_math is not since that also guards some operations Miri does not support.
Unfortunately target_has_reliable_f128_math guards a wide range of things, from stuff Miri can trivially support via softfloats (like mul_add) to things Miri cannot support because f128 isn't reliable on many of our targets (like pow, sin, log, etc).
There was a problem hiding this comment.
Hm, interesting. Maybe that suggests we need f128_simple_math? :)
Does the f16 situation differ for some reason (e.g., possible to add tables for literally all values?)?
If we think this is the right thing to do happy to r+ as-is though.
There was a problem hiding this comment.
For f16 its similar. All the hosts that we build Miri on support it well enough that we can at least link pow, sin and friends without causing issues, and we set target_has_reliable_f16_math if the host has that flag. But actually for operations that we implement via softfloats we'd want target_has_reliable_f16_math to be unconditionally true, it's only the transcendental operations where hosts matter.
However it's probably not worth splitting up the cfg flag just for Miri.
Tons of existing tests have cfg(any(miri, target_has_reliable_f128_math)) so the new one here is consistent.
For f16 tons of tests actually use #[cfg(target_has_reliable_f16)] { which contradicts the intent of that flag as it was explained to me... 🤷 .
There was a problem hiding this comment.
which contradicts the intent of that flag as it was explained to me
Also FWIW both f16 and f128 guard e.g. the tests for recip (1.0 / self) with the has_reliable flag, not the has_reliable_math flag, despite @tgross35 explaining to me that has_reliable is just for the ABI and bit-level operations (maybe including abs and copysign?) and has_reliable_math is for anything that needs actual math, rounding, or anything like that. For other operations (e.g. max, floor), f16 uses has_reliable but f128 uses has_reliable_math. So it's all quite inconsistent and messy I think.
There was a problem hiding this comment.
Linking discussion #t-compiler > has_reliable_{f16,f128} vs has_reliable_{f16,f128}_math
|
@bors squash msg="Add mul_add_relaxed methods for floating-point types" |
This comment has been minimized.
This comment has been minimized.
|
🔨 2 commits were squashed into 3b7025f. |
e83763c to
3b7025f
Compare
|
Any special-casing of Miri in the standard library requires review. cc @rust-lang/miri |
|
@bors r+ rollup |
…rust-lang#151770, r=Mark-Simulacrum Add mul_add_relaxed methods for floating-point types Implements mul_add_relaxed for f16, f32, f64, and f128, which computes (self * a) + b with relaxed precision semantics. Unlike mul_add which guarantees a fused operation, this variant allows the compiler to choose between fused or separate operations based on target performance. This fills the gap between the precision-guaranteed mul_add and the fully-optimizable algebraic operators, providing target-specific optimization while maintaining reasonable floating-point semantics. Tracking issue: rust-lang#151770
…uwer Rollup of 6 pull requests Successful merges: - #159188 (Always generate private and hidden items in JSON docs of the stdlib) - #159567 (Update rustc crate crossbeam-epoch to 0.9.20) - #150732 (Convert `-Ctarget-cpu` into a target-modifier for AVR, AMDGCN and NVPTX ) - #151793 (Add mul_add_relaxed methods for floating-point types) - #159549 (restrict const-eval-related 'content' triggers to library/ folder) - #159570 (fix ICE in opsem inhabitedness check)
|
💔 I suspect this PR failed tests as part of a rollup After fixing the problem, consider running a try job for the failed job before re-approving. Link to failure: #159573 (comment) |
|
This pull request was unapproved. This PR was contained in a rollup (#159573), which was unapproved. |
| assert_eq!(black_box(1.0_f64).mul_add_relaxed(1.0, 1.0), 2.0); | ||
|
|
||
| let r = black_box(0.1_f64).mul_add_relaxed(0.1, -0.01); | ||
| assert!(r == 9.020562075079397e-19 || r == 1.734723475976807e-18); |
There was a problem hiding this comment.
you can now make this
| assert!(r == 9.020562075079397e-19 || r == 1.734723475976807e-18); | |
| assert_matches!(r, 9.020562075079397e-19 | 1.734723475976807e-18); |
and that should not just print that it failed, but also show the value that didn't match.
View all comments
Implements mul_add_relaxed for f16, f32, f64, and f128, which computes (self * a) + b with relaxed precision semantics. Unlike mul_add which guarantees a fused operation, this variant allows the compiler to choose between fused or separate operations based on target performance.
This fills the gap between the precision-guaranteed mul_add and the fully-optimizable algebraic operators, providing target-specific optimization while maintaining reasonable floating-point semantics.
Tracking issue: #151770