Skip to content

Add fallback for intrinsics::fabs#159605

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
N1ark:fabs-fallback
Jul 23, 2026
Merged

Add fallback for intrinsics::fabs#159605
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
N1ark:fabs-fallback

Conversation

@N1ark

@N1ark N1ark commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Add a fallback for the fabs intrinsic. Because it uses const traits and const ops it required adding rustc_const_unstable -- i'm not certain it's right but it seems to make sense. I also added #[miri::intrinsic_fallback_is_spec], though im not sure if I need to modify the const eval code to remove fabs handling or to remove it from any of the backends

r? folkertdev

@rustbot

rustbot commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Any special-casing of Miri in the standard library requires review.

cc @rust-lang/miri

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

⚠️ #[miri::intrinsic_fallback_is_spec] must only be used if the function actively checks for all UB cases,
and explores the possible non-determinism of the intrinsic.

cc @rust-lang/miri

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

@folkertdev folkertdev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm still skeptical that this is an improvement over the naive "just duplicate it 4 times" approach.

View changes since this review

Comment thread library/core/src/intrinsics/bounds.rs Outdated
Comment on lines +3634 to +3643
#[miri::intrinsic_fallback_is_spec]
pub const fn fabs<T: bounds::FloatPrimitive>(x: T) -> T {
// SAFETY: the implementation of `FloatPrimitive` guarantees that `T` is a
// floating-point type, and that `T::Unsigned` is the corresponding unsigned
// integer type with the same size as `T`. Both are valid for all bit patterns.
let bits: T::Unsigned = unsafe { transmute_unchecked(x) };
let abs = bits & !T::SIGN_MASK;
// SAFETY: same as above
unsafe { transmute_unchecked(abs) }
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@RalfJung does this spark joy? I'd much rather have the one-liner duplicated 4 times than the (trivial, but still) unsafety and const trait stuff that is required.

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.

The question is whether it sparks more or less joy than copy-paste. The status quo is definitely not joyful. ;)

But yeah I agree needing unsafe is pretty bad.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

does it spark joy now ? ^-^

pub const fn fabs<T: const bounds::FloatPrimitive>(x: T) -> T {
    T::from_bits(x.to_bits() & !T::SIGN_MASK)
}

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.

Yes that seems exactly as readable as the per-type version, just less duplicated :)

Comment on lines +57 to +67
#[rustc_const_unstable(feature = "core_intrinsics", issue = "none")]
const unsafe impl FloatPrimitive for f16 {
type Unsigned = u16;
const SIGN_MASK: Self::Unsigned = f16::SIGN_MASK;
fn to_bits(self) -> Self::Unsigned {
f16::to_bits(self)
}
fn from_bits(bits: Self::Unsigned) -> Self {
f16::from_bits(bits)
}
}

@N1ark N1ark Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this can be macro'd if you'd rather i have no strong opinions on that

View changes since the review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's hold off on using macros, this seems manageable now and a macro won't work for fallbacks that need a per-type implementation (e.g. sin or fma)

Comment thread library/core/src/intrinsics/bounds.rs Outdated

@folkertdev folkertdev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So how will this work for the heterogeneous fallbacks (like fma)? Just add more methods to the trait?

View changes since this review

Comment on lines +57 to +67
#[rustc_const_unstable(feature = "core_intrinsics", issue = "none")]
const unsafe impl FloatPrimitive for f16 {
type Unsigned = u16;
const SIGN_MASK: Self::Unsigned = f16::SIGN_MASK;
fn to_bits(self) -> Self::Unsigned {
f16::to_bits(self)
}
fn from_bits(bits: Self::Unsigned) -> Self {
f16::from_bits(bits)
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's hold off on using macros, this seems manageable now and a macro won't work for fallbacks that need a per-type implementation (e.g. sin or fma)

Comment thread library/core/src/intrinsics/bounds.rs Outdated
@RalfJung

Copy link
Copy Markdown
Member

So how will this work for the heterogeneous fallbacks (like fma)? Just add more methods to the trait?

Either that, more a per-operation trait defined locally by a macro.

@N1ark

N1ark commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author
edit: Ralf beat me to it

So how will this work for the heterogeneous fallbacks (like fma)? Just add more methods to the trait?

for those i think what's easiest (which @RalfJung ) commented on Zulip. i dont think i would format it like that, but something along the lines of

intrinsic_dispatch_on_type! {
    pub fn fma<T: bounds::FloatPrimitive>(x: T, y: T, z: T) -> T;
    f16 => {
      fma(x as f64, y as f64, z as f64) as f16
    }
    f32 => { 
      libm::fmaf(x, y, z)
    }
    // etc
}

which then would create a trait for that specific intrinsic that does the thing, adds it to the trait bound and what not? or add it to the FloatPrimitive trait directly, i dont feel strongly abt this

yes it duplicates the impl but it still allows a pretty good cleanup in the rest of the compiler which personally i think is worth the code here (also avoids duplicating comments which can be quite long and technical:) )

@folkertdev

Copy link
Copy Markdown
Contributor

Well let's see how this works out in practice. One thing to note is that the GCC and Cranelift backends don't yet make use of some of the newly-added default (e.g. rust-lang/rustc_codegen_cranelift#1675 can hopefully land tomorrow when nightly include the portable_simd sync) so there may be merge conflicts if you make more progress here in the coming days.

@bors r+

@rust-bors

rust-bors Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 74fb1f9 has been approved by folkertdev

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 22, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jul 22, 2026
Add fallback for `intrinsics::fabs`

Add a fallback for the `fabs` intrinsic. Because it uses const traits and const ops it required adding `rustc_const_unstable` -- i'm not certain it's right but it seems to make sense. I also added `#[miri::intrinsic_fallback_is_spec]`, though im not sure if I need to modify the const eval code to remove `fabs` handling or to remove it from any of the backends

r? folkertdev
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jul 22, 2026
Add fallback for `intrinsics::fabs`

Add a fallback for the `fabs` intrinsic. Because it uses const traits and const ops it required adding `rustc_const_unstable` -- i'm not certain it's right but it seems to make sense. I also added `#[miri::intrinsic_fallback_is_spec]`, though im not sure if I need to modify the const eval code to remove `fabs` handling or to remove it from any of the backends

r? folkertdev
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Jul 22, 2026
Add fallback for `intrinsics::fabs`

Add a fallback for the `fabs` intrinsic. Because it uses const traits and const ops it required adding `rustc_const_unstable` -- i'm not certain it's right but it seems to make sense. I also added `#[miri::intrinsic_fallback_is_spec]`, though im not sure if I need to modify the const eval code to remove `fabs` handling or to remove it from any of the backends

r? folkertdev
rust-bors Bot pushed a commit that referenced this pull request Jul 23, 2026
Rollup of 8 pull requests

Successful merges:

 - #159504 (Abort const-eval queries early when there are generics in the type)
 - #159523 (std: fix Xous UDP recv length over-report and OOB panic)
 - #159605 (Add fallback for `intrinsics::fabs`)
 - #159699 (bump std libc to 0.2.189)
 - #159306 (Add new variant to iterating-updating-mutref borrowck test)
 - #159346 (fs::hard_link: use linkat on Android)
 - #159513 (Consider `()` as suspicious only when expecting `!` for runtime symbols)
 - #159734 (Document the link_section attribute)
@rust-bors
rust-bors Bot merged commit c5f9a51 into rust-lang:main Jul 23, 2026
13 checks passed
@rustbot rustbot added this to the 1.99.0 milestone Jul 23, 2026
rust-timer added a commit that referenced this pull request Jul 23, 2026
Rollup merge of #159605 - N1ark:fabs-fallback, r=folkertdev

Add fallback for `intrinsics::fabs`

Add a fallback for the `fabs` intrinsic. Because it uses const traits and const ops it required adding `rustc_const_unstable` -- i'm not certain it's right but it seems to make sense. I also added `#[miri::intrinsic_fallback_is_spec]`, though im not sure if I need to modify the const eval code to remove `fabs` handling or to remove it from any of the backends

r? folkertdev
moabo3li pushed a commit to moabo3li/miri that referenced this pull request Jul 23, 2026
Rollup of 8 pull requests

Successful merges:

 - rust-lang/rust#159504 (Abort const-eval queries early when there are generics in the type)
 - rust-lang/rust#159523 (std: fix Xous UDP recv length over-report and OOB panic)
 - rust-lang/rust#159605 (Add fallback for `intrinsics::fabs`)
 - rust-lang/rust#159699 (bump std libc to 0.2.189)
 - rust-lang/rust#159306 (Add new variant to iterating-updating-mutref borrowck test)
 - rust-lang/rust#159346 (fs::hard_link: use linkat on Android)
 - rust-lang/rust#159513 (Consider `()` as suspicious only when expecting `!` for runtime symbols)
 - rust-lang/rust#159734 (Document the link_section attribute)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.

4 participants