Skip to content

Add mul_add_relaxed methods for floating-point types - #151793

Open
landsharkiest wants to merge 3 commits into
rust-lang:mainfrom
landsharkiest:float_mul_add_relaxed-#151770
Open

landsharkiest wants to merge 3 commits into
rust-lang:mainfrom
landsharkiest:float_mul_add_relaxed-#151770

Conversation

@landsharkiest

@landsharkiest landsharkiest commented Jan 28, 2026 •

Copy link
Copy Markdown

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

try-job: dist-i586-gnu-i586-i686-musl

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jan 28, 2026
@rustbot

rustbot commented Jan 28, 2026

Copy link
Copy Markdown
Collaborator

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

Comment thread tests/ui/intrinsics/float-mul-add-relaxed.rs
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

Comment thread library/core/src/num/f32.rs Outdated
@rust-log-analyzer

This comment has been minimized.

@Mark-Simulacrum Mark-Simulacrum added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 1, 2026
@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@RalfJung

RalfJung commented Jul 16, 2026 •

Copy link
Copy Markdown
Member

@landsharkiest friendly reminder that this PR is waiting for you to react to the reviewer's feedback and to fix CI. :)
if you no longer have time to work on this, that's fine -- just let us know so the task can be picked up by someone else.

@folkertdev

Copy link
Copy Markdown
Contributor

Another thing, please update the doc comment of the intrinsics to point to the public methods, like here

/// The stabilized version of this intrinsic is 
/// [`f128::mul_add`](../../std/primitive.f128.html#method.mul_add) 

/// Returns `a * b + c` for `f128` values.
///
/// The stabilized version of this intrinsic is
/// [`f128::mul_add`](../../std/primitive.f128.html#method.mul_add)
#[rustc_intrinsic_const_stable_indirect]
#[rustc_intrinsic]
#[rustc_nounwind]
pub const fn fmaf128(a: f128, b: f128, c: f128) -> f128;
/// Returns `a * b + c` for `f16` values, non-deterministically executing
/// either a fused multiply-add or two operations with rounding of the
/// intermediate result.
///
/// The operation is fused if the code generator determines that target
/// instruction set has support for a fused operation, and that the fused
/// operation is more efficient than the equivalent, separate pair of mul
/// and add instructions. It is unspecified whether or not a fused operation
/// is selected, and that may depend on optimization level and context, for
/// example.
#[rustc_intrinsic]
#[rustc_nounwind]
pub const fn fmuladdf16(a: f16, b: f16, c: f16) -> f16;

We use the prasing of "stabilized" here even if the methods are not actually stable.

@landsharkiest
landsharkiest force-pushed the float_mul_add_relaxed-#151770 branch from 0ca5122 to 174bea7 Compare July 18, 2026 01:25
@rustbot

rustbot commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.

cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

@rustbot

This comment has been minimized.

@landsharkiest

Copy link
Copy Markdown
Author

@landsharkiest friendly reminder that this PR is waiting for you to react to the reviewer's feedback and to fix CI. :) if you no longer have time to work on this, that's fine -- just let us know so the task can be picked up by someone else.

Sorry got caught up in school and job searching, will finally put this away! :)

@rust-log-analyzer

This comment has been minimized.

@landsharkiest
landsharkiest force-pushed the float_mul_add_relaxed-#151770 branch from 174bea7 to 67e0947 Compare July 18, 2026 02:44
@scottmcm

Copy link
Copy Markdown
Member

i586 is known sketchy for floats always, right? Could potentially just skip them for that...

@folkertdev

Copy link
Copy Markdown
Contributor

Yeah some tests were already skipped since the last CI failure, seems like a bit more ignoring is needed.

https://triagebot.infra.rust-lang.org/gh-changes-since/rust-lang/rust/151793/234c31cd674e11703f15d290cba7ff81dfe8b4b8..3b7025f3a35e74943089a7e2dfe139bf2f821a89

@rust-log-analyzer

This comment has been minimized.

@RalfJung

Copy link
Copy Markdown
Member

Yeah if you check precise results then it's not surprising to see failures on that target.

Comment thread library/core/src/num/f16.rs Outdated
/// # #[cfg(target_has_reliable_f16)] {
///
/// let result = 1.0f16.mul_add_relaxed(2.0, 3.0);
/// assert_eq!(result, 5.0);

@tgross35 tgross35 Aug 4, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add the (0.1, 0.1, -0.01) example for f16 and f128 too? Answers should be either -7.6e-6 or -7.03e-6 for f16, 1.5046327690525280101999827676444745E-36 or 7.824090399073145653039910391751267E-37 for f128.

View changes since the review

@rust-bors

This comment has been minimized.

On 32-bit x86 without SSE2, x87 rounds the f64 product to a 64-bit
significand rather than keeping it exact or rounding it to 53 bits, so
the doc example can produce a value (9.0209e-19) that is neither the
fused nor the unfused result. Skip that check there, like other float
doctests do for i586. The f32 example is unaffected: its intermediate
values fit in the x87 significand, so it always yields one of the two
allowed results.

Also add the fused-or-unfused example to f16 and f128, as requested
in review.
@landsharkiest
landsharkiest force-pushed the float_mul_add_relaxed-#151770 branch from ace8a46 to 335e78f Compare September 26, 2026 16:11
@rustbot

rustbot commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator

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.

@RalfJung

Copy link
Copy Markdown
Member

r? @folkertdev

@landsharkiest remember to post @rustbot ready when this PR is ready for review again.

Comment thread library/core/src/num/f128.rs Outdated
Comment thread library/core/src/num/f128.rs Outdated
@RalfJung

Copy link
Copy Markdown
Member

@bors try

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Sep 26, 2026
…r=<try>

Add mul_add_relaxed methods for floating-point types
Say that even two invocations with the same inputs may produce
different results, and remove the `1.0.mul_add_relaxed(2.0, 3.0)`
example: it is atypical, since the fused and unfused results are the
same there. The fused-or-unfused example remains.
@RalfJung

Copy link
Copy Markdown
Member

@bors try

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Sep 26, 2026
…r=<try>

Add mul_add_relaxed methods for floating-point types
@RalfJung

RalfJung commented Sep 26, 2026 •

Copy link
Copy Markdown
Member

It seems to ignore try-jobs in the PR description? Strange.
EDIT: Ah, it has to be "try-job". Without the s.

@bors try jobs=dist-i586-gnu-i586-i686-musl

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Sep 26, 2026
…r=<try>

Add mul_add_relaxed methods for floating-point types


try-job: dist-i586-gnu-i586-i686-musl
@rust-bors

rust-bors Bot commented Sep 26, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: d7f43bc (d7f43bc5cd6a4b69dc4f074274243879f840c658)
Base parent: a22b02e (a22b02eaecd6ac937d752139c79d0159c725932d)

@landsharkiest

Copy link
Copy Markdown
Author

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Sep 26, 2026

@tgross35 tgross35 left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but please squash

View changes since this review

This branch has not been deployed

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

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants