-
Notifications
You must be signed in to change notification settings - Fork 211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add builtins for f16
/f128
float conversions
#593
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,8 +52,10 @@ where | |
// destination format. We can convert by simply right-shifting with | ||
// rounding and adjusting the exponent. | ||
abs_result = (a_abs >> sign_bits_delta).cast(); | ||
let tmp = src_exp_bias.wrapping_sub(dst_exp_bias) << R::SIGNIFICAND_BITS; | ||
abs_result = abs_result.wrapping_sub(tmp.cast()); | ||
// Cast before shifting to prevent overflow. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm having trouble understand how exactly this helps prevent overflows. Aren't you casting to a smaller size (u16) here instead of operating as a u32? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Amanieu This is indeed not an issue for truncation to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I missed that. LGTM. |
||
let bias_diff: R::Int = src_exp_bias.wrapping_sub(dst_exp_bias).cast(); | ||
let tmp = bias_diff << R::SIGNIFICAND_BITS; | ||
abs_result = abs_result.wrapping_sub(tmp); | ||
|
||
let round_bits = a_abs & round_mask; | ||
if round_bits > halfway { | ||
|
@@ -67,13 +69,17 @@ where | |
// a is NaN. | ||
// Conjure the result by beginning with infinity, setting the qNaN | ||
// bit and inserting the (truncated) trailing NaN field. | ||
abs_result = (dst_inf_exp << R::SIGNIFICAND_BITS).cast(); | ||
// Cast before shifting to prevent overflow. | ||
let dst_inf_exp: R::Int = dst_inf_exp.cast(); | ||
abs_result = dst_inf_exp << R::SIGNIFICAND_BITS; | ||
abs_result |= dst_qnan; | ||
abs_result |= dst_nan_code | ||
& ((a_abs & src_nan_code) >> (F::SIGNIFICAND_BITS - R::SIGNIFICAND_BITS)).cast(); | ||
} else if a_abs >= overflow { | ||
// a overflows to infinity. | ||
abs_result = (dst_inf_exp << R::SIGNIFICAND_BITS).cast(); | ||
// Cast before shifting to prevent overflow. | ||
let dst_inf_exp: R::Int = dst_inf_exp.cast(); | ||
abs_result = dst_inf_exp << R::SIGNIFICAND_BITS; | ||
} else { | ||
// a underflows on conversion to the destination type or is an exact | ||
// zero. The result may be a denormal or zero. Extract the exponent | ||
|
@@ -124,3 +130,44 @@ intrinsics! { | |
a as f32 | ||
} | ||
} | ||
|
||
#[cfg(not(feature = "no-f16-f128"))] | ||
intrinsics! { | ||
#[avr_skip] | ||
#[aapcs_on_arm] | ||
#[arm_aeabi_alias = __aeabi_f2h] | ||
pub extern "C" fn __truncsfhf2(a: f32) -> f16 { | ||
trunc(a) | ||
} | ||
|
||
#[avr_skip] | ||
#[aapcs_on_arm] | ||
pub extern "C" fn __gnu_f2h_ieee(a: f32) -> f16 { | ||
trunc(a) | ||
} | ||
|
||
#[avr_skip] | ||
#[aapcs_on_arm] | ||
#[arm_aeabi_alias = __aeabi_d2h] | ||
pub extern "C" fn __truncdfhf2(a: f64) -> f16 { | ||
trunc(a) | ||
} | ||
|
||
#[avr_skip] | ||
#[aapcs_on_arm] | ||
pub extern "C" fn __trunctfhf2(a: f128) -> f16 { | ||
trunc(a) | ||
} | ||
|
||
#[avr_skip] | ||
#[aapcs_on_arm] | ||
pub extern "C" fn __trunctfsf2(a: f128) -> f32 { | ||
trunc(a) | ||
} | ||
|
||
#[avr_skip] | ||
#[aapcs_on_arm] | ||
pub extern "C" fn __trunctfdf2(a: f128) -> f64 { | ||
trunc(a) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Features should usually be additive and not take things away -- so, can't we have an "f16-f128" feature that enables these intrinsics, and have them off by default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that was just following the
no-asm
feature above, but they could probably both be flipped to be additiveThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This "adds" support for codegen backends that don't support f16/f128. If a
f16-f128
feature is used instead, liballoc would likely enable it when depending on compiler-builtins, which makes it impossible to disable the f16/f128 intrinsics using--features
when invoking cargo, instead requiring the standard library sources to be patched.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... what?^^ I am confused. "Additive" is always meant in a semver way when it comes to cargo feature: if a dependent builds without the feature, it should also build with the feature. Don't try to re-define well-established terms, please. The leading "no" is also a dead giveaway that this not a negative feature, removing things, rather than adding them.
We are currently (once that PR lands) setting this feature in
std
because of said codegen backends. But that means buildingcore
alone will still fail with these codegen backends. It all makes little sense to me.That sounds wrong to me. Instead, bootstrap should enable the feature when it deems them supported by the environment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The build system of these codegen backends should set it, not libstd. For example for no-asm, this is what cg_clif does when building the standard library:
https://github.com/rust-lang/rustc_codegen_cranelift/blob/6db27529ddbb6d94e0c990e527aa8341c3d85a79/build_system/build_sysroot.rs#L279
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can accept the answer "this is a hack, compiler_builtins is special and has a single consumer and so we can get away with negative features".