Add fallback for intrinsics::fabs#159605
Conversation
|
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 cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr
cc @rust-lang/miri |
| #[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) } | ||
| } |
There was a problem hiding this comment.
@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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)
}There was a problem hiding this comment.
Yes that seems exactly as readable as the per-type version, just less duplicated :)
| #[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) | ||
| } | ||
| } |
There was a problem hiding this comment.
this can be macro'd if you'd rather i have no strong opinions on that
There was a problem hiding this comment.
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)
| #[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) | ||
| } | ||
| } |
There was a problem hiding this comment.
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)
Either that, more a per-operation trait defined locally by a macro. |
edit: Ralf beat me to it
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 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:) ) |
|
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 @bors r+ |
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
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
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
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)
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
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)
Add a fallback for the
fabsintrinsic. Because it uses const traits and const ops it required addingrustc_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 removefabshandling or to remove it from any of the backendsr? folkertdev