Add intrinsic fallback for {minimum,maximum}{16,32,64,128}

This commit is contained in:
Urgau
2025-05-08 22:13:13 +02:00
parent e7247df590
commit dc69020aa4
5 changed files with 108 additions and 164 deletions

View File

@@ -3989,9 +3989,19 @@ pub const fn minnumf128(x: f128, y: f128) -> f128;
/// Therefore, implementations must not require the user to uphold
/// any safety invariants.
#[rustc_nounwind]
#[rustc_intrinsic]
#[cfg(not(bootstrap))]
pub const fn minimumf16(x: f16, y: f16) -> f16;
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
pub const fn minimumf16(x: f16, y: f16) -> f16 {
if x < y {
x
} else if y < x {
y
} else if x == y {
if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
} else {
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
x + y
}
}
/// Returns the minimum (IEEE 754-2019 minimum) of two `f32` values.
///
@@ -4000,9 +4010,19 @@ pub const fn minimumf16(x: f16, y: f16) -> f16;
/// Therefore, implementations must not require the user to uphold
/// any safety invariants.
#[rustc_nounwind]
#[rustc_intrinsic]
#[cfg(not(bootstrap))]
pub const fn minimumf32(x: f32, y: f32) -> f32;
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
pub const fn minimumf32(x: f32, y: f32) -> f32 {
if x < y {
x
} else if y < x {
y
} else if x == y {
if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
} else {
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
x + y
}
}
/// Returns the minimum (IEEE 754-2019 minimum) of two `f64` values.
///
@@ -4011,9 +4031,19 @@ pub const fn minimumf32(x: f32, y: f32) -> f32;
/// Therefore, implementations must not require the user to uphold
/// any safety invariants.
#[rustc_nounwind]
#[rustc_intrinsic]
#[cfg(not(bootstrap))]
pub const fn minimumf64(x: f64, y: f64) -> f64;
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
pub const fn minimumf64(x: f64, y: f64) -> f64 {
if x < y {
x
} else if y < x {
y
} else if x == y {
if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
} else {
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
x + y
}
}
/// Returns the minimum (IEEE 754-2019 minimum) of two `f128` values.
///
@@ -4022,9 +4052,19 @@ pub const fn minimumf64(x: f64, y: f64) -> f64;
/// Therefore, implementations must not require the user to uphold
/// any safety invariants.
#[rustc_nounwind]
#[rustc_intrinsic]
#[cfg(not(bootstrap))]
pub const fn minimumf128(x: f128, y: f128) -> f128;
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
pub const fn minimumf128(x: f128, y: f128) -> f128 {
if x < y {
x
} else if y < x {
y
} else if x == y {
if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
} else {
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
x + y
}
}
/// Returns the maximum (IEEE 754-2008 maxNum) of two `f16` values.
///
@@ -4087,9 +4127,18 @@ pub const fn maxnumf128(x: f128, y: f128) -> f128;
/// Therefore, implementations must not require the user to uphold
/// any safety invariants.
#[rustc_nounwind]
#[rustc_intrinsic]
#[cfg(not(bootstrap))]
pub const fn maximumf16(x: f16, y: f16) -> f16;
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
pub const fn maximumf16(x: f16, y: f16) -> f16 {
if x > y {
x
} else if y > x {
y
} else if x == y {
if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
} else {
x + y
}
}
/// Returns the maximum (IEEE 754-2019 maximum) of two `f32` values.
///
@@ -4098,9 +4147,18 @@ pub const fn maximumf16(x: f16, y: f16) -> f16;
/// Therefore, implementations must not require the user to uphold
/// any safety invariants.
#[rustc_nounwind]
#[rustc_intrinsic]
#[cfg(not(bootstrap))]
pub const fn maximumf32(x: f32, y: f32) -> f32;
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
pub const fn maximumf32(x: f32, y: f32) -> f32 {
if x > y {
x
} else if y > x {
y
} else if x == y {
if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
} else {
x + y
}
}
/// Returns the maximum (IEEE 754-2019 maximum) of two `f64` values.
///
@@ -4109,9 +4167,18 @@ pub const fn maximumf32(x: f32, y: f32) -> f32;
/// Therefore, implementations must not require the user to uphold
/// any safety invariants.
#[rustc_nounwind]
#[rustc_intrinsic]
#[cfg(not(bootstrap))]
pub const fn maximumf64(x: f64, y: f64) -> f64;
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
pub const fn maximumf64(x: f64, y: f64) -> f64 {
if x > y {
x
} else if y > x {
y
} else if x == y {
if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
} else {
x + y
}
}
/// Returns the maximum (IEEE 754-2019 maximum) of two `f128` values.
///
@@ -4120,9 +4187,18 @@ pub const fn maximumf64(x: f64, y: f64) -> f64;
/// Therefore, implementations must not require the user to uphold
/// any safety invariants.
#[rustc_nounwind]
#[rustc_intrinsic]
#[cfg(not(bootstrap))]
pub const fn maximumf128(x: f128, y: f128) -> f128;
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
pub const fn maximumf128(x: f128, y: f128) -> f128 {
if x > y {
x
} else if y > x {
y
} else if x == y {
if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
} else {
x + y
}
}
/// Returns the absolute value of an `f16`.
///

View File

@@ -755,25 +755,9 @@ impl f128 {
#[inline]
#[unstable(feature = "f128", issue = "116909")]
// #[unstable(feature = "float_minimum_maximum", issue = "91079")]
#[rustc_const_unstable(feature = "f128", issue = "116909")]
#[must_use = "this returns the result of the comparison, without modifying either input"]
pub const fn maximum(self, other: f128) -> f128 {
#[cfg(not(bootstrap))]
{
intrinsics::maximumf128(self, other)
}
#[cfg(bootstrap)]
{
if self > other {
self
} else if other > self {
other
} else if self == other {
if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
} else {
self + other
}
}
intrinsics::maximumf128(self, other)
}
/// Returns the minimum of the two numbers, propagating NaN.
@@ -804,26 +788,9 @@ impl f128 {
#[inline]
#[unstable(feature = "f128", issue = "116909")]
// #[unstable(feature = "float_minimum_maximum", issue = "91079")]
#[rustc_const_unstable(feature = "f128", issue = "116909")]
#[must_use = "this returns the result of the comparison, without modifying either input"]
pub const fn minimum(self, other: f128) -> f128 {
#[cfg(not(bootstrap))]
{
intrinsics::minimumf128(self, other)
}
#[cfg(bootstrap)]
{
if self < other {
self
} else if other < self {
other
} else if self == other {
if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
} else {
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
self + other
}
}
intrinsics::minimumf128(self, other)
}
/// Calculates the midpoint (average) between `self` and `rhs`.

View File

@@ -744,25 +744,9 @@ impl f16 {
#[inline]
#[unstable(feature = "f16", issue = "116909")]
// #[unstable(feature = "float_minimum_maximum", issue = "91079")]
#[rustc_const_unstable(feature = "f16", issue = "116909")]
#[must_use = "this returns the result of the comparison, without modifying either input"]
pub const fn maximum(self, other: f16) -> f16 {
#[cfg(not(bootstrap))]
{
intrinsics::maximumf16(self, other)
}
#[cfg(bootstrap)]
{
if self > other {
self
} else if other > self {
other
} else if self == other {
if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
} else {
self + other
}
}
intrinsics::maximumf16(self, other)
}
/// Returns the minimum of the two numbers, propagating NaN.
@@ -792,26 +776,9 @@ impl f16 {
#[inline]
#[unstable(feature = "f16", issue = "116909")]
// #[unstable(feature = "float_minimum_maximum", issue = "91079")]
#[rustc_const_unstable(feature = "f16", issue = "116909")]
#[must_use = "this returns the result of the comparison, without modifying either input"]
pub const fn minimum(self, other: f16) -> f16 {
#[cfg(not(bootstrap))]
{
intrinsics::minimumf16(self, other)
}
#[cfg(bootstrap)]
{
if self < other {
self
} else if other < self {
other
} else if self == other {
if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
} else {
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
self + other
}
}
intrinsics::minimumf16(self, other)
}
/// Calculates the midpoint (average) between `self` and `rhs`.

View File

@@ -942,25 +942,9 @@ impl f32 {
/// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
#[must_use = "this returns the result of the comparison, without modifying either input"]
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
#[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
#[inline]
pub const fn maximum(self, other: f32) -> f32 {
#[cfg(not(bootstrap))]
{
intrinsics::maximumf32(self, other)
}
#[cfg(bootstrap)]
{
if self > other {
self
} else if other > self {
other
} else if self == other {
if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
} else {
self + other
}
}
intrinsics::maximumf32(self, other)
}
/// Returns the minimum of the two numbers, propagating NaN.
@@ -985,26 +969,9 @@ impl f32 {
/// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
#[must_use = "this returns the result of the comparison, without modifying either input"]
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
#[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
#[inline]
pub const fn minimum(self, other: f32) -> f32 {
#[cfg(not(bootstrap))]
{
intrinsics::minimumf32(self, other)
}
#[cfg(bootstrap)]
{
if self < other {
self
} else if other < self {
other
} else if self == other {
if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
} else {
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
self + other
}
}
intrinsics::minimumf32(self, other)
}
/// Calculates the midpoint (average) between `self` and `rhs`.

View File

@@ -960,25 +960,9 @@ impl f64 {
/// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
#[must_use = "this returns the result of the comparison, without modifying either input"]
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
#[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
#[inline]
pub const fn maximum(self, other: f64) -> f64 {
#[cfg(not(bootstrap))]
{
intrinsics::maximumf64(self, other)
}
#[cfg(bootstrap)]
{
if self > other {
self
} else if other > self {
other
} else if self == other {
if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
} else {
self + other
}
}
intrinsics::maximumf64(self, other)
}
/// Returns the minimum of the two numbers, propagating NaN.
@@ -1003,26 +987,9 @@ impl f64 {
/// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
#[must_use = "this returns the result of the comparison, without modifying either input"]
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
#[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
#[inline]
pub const fn minimum(self, other: f64) -> f64 {
#[cfg(not(bootstrap))]
{
intrinsics::minimumf64(self, other)
}
#[cfg(bootstrap)]
{
if self < other {
self
} else if other < self {
other
} else if self == other {
if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
} else {
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
self + other
}
}
intrinsics::minimumf64(self, other)
}
/// Calculates the midpoint (average) between `self` and `rhs`.