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 /// Therefore, implementations must not require the user to uphold
/// any safety invariants. /// any safety invariants.
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[cfg_attr(not(bootstrap), rustc_intrinsic)]
#[cfg(not(bootstrap))] pub const fn minimumf16(x: f16, y: f16) -> f16 {
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. /// 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 /// Therefore, implementations must not require the user to uphold
/// any safety invariants. /// any safety invariants.
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[cfg_attr(not(bootstrap), rustc_intrinsic)]
#[cfg(not(bootstrap))] pub const fn minimumf32(x: f32, y: f32) -> f32 {
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. /// 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 /// Therefore, implementations must not require the user to uphold
/// any safety invariants. /// any safety invariants.
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[cfg_attr(not(bootstrap), rustc_intrinsic)]
#[cfg(not(bootstrap))] pub const fn minimumf64(x: f64, y: f64) -> f64 {
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. /// 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 /// Therefore, implementations must not require the user to uphold
/// any safety invariants. /// any safety invariants.
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[cfg_attr(not(bootstrap), rustc_intrinsic)]
#[cfg(not(bootstrap))] pub const fn minimumf128(x: f128, y: f128) -> f128 {
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. /// 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 /// Therefore, implementations must not require the user to uphold
/// any safety invariants. /// any safety invariants.
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[cfg_attr(not(bootstrap), rustc_intrinsic)]
#[cfg(not(bootstrap))] pub const fn maximumf16(x: f16, y: f16) -> f16 {
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. /// 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 /// Therefore, implementations must not require the user to uphold
/// any safety invariants. /// any safety invariants.
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[cfg_attr(not(bootstrap), rustc_intrinsic)]
#[cfg(not(bootstrap))] pub const fn maximumf32(x: f32, y: f32) -> f32 {
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. /// 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 /// Therefore, implementations must not require the user to uphold
/// any safety invariants. /// any safety invariants.
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[cfg_attr(not(bootstrap), rustc_intrinsic)]
#[cfg(not(bootstrap))] pub const fn maximumf64(x: f64, y: f64) -> f64 {
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. /// 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 /// Therefore, implementations must not require the user to uphold
/// any safety invariants. /// any safety invariants.
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[cfg_attr(not(bootstrap), rustc_intrinsic)]
#[cfg(not(bootstrap))] pub const fn maximumf128(x: f128, y: f128) -> f128 {
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`. /// Returns the absolute value of an `f16`.
/// ///

View File

@@ -755,26 +755,10 @@ impl f128 {
#[inline] #[inline]
#[unstable(feature = "f128", issue = "116909")] #[unstable(feature = "f128", issue = "116909")]
// #[unstable(feature = "float_minimum_maximum", issue = "91079")] // #[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"] #[must_use = "this returns the result of the comparison, without modifying either input"]
pub const fn maximum(self, other: f128) -> f128 { pub const fn maximum(self, other: f128) -> f128 {
#[cfg(not(bootstrap))]
{
intrinsics::maximumf128(self, other) 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
}
}
}
/// Returns the minimum of the two numbers, propagating NaN. /// Returns the minimum of the two numbers, propagating NaN.
/// ///
@@ -804,27 +788,10 @@ impl f128 {
#[inline] #[inline]
#[unstable(feature = "f128", issue = "116909")] #[unstable(feature = "f128", issue = "116909")]
// #[unstable(feature = "float_minimum_maximum", issue = "91079")] // #[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"] #[must_use = "this returns the result of the comparison, without modifying either input"]
pub const fn minimum(self, other: f128) -> f128 { pub const fn minimum(self, other: f128) -> f128 {
#[cfg(not(bootstrap))]
{
intrinsics::minimumf128(self, other) 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
}
}
}
/// Calculates the midpoint (average) between `self` and `rhs`. /// Calculates the midpoint (average) between `self` and `rhs`.
/// ///

View File

@@ -744,26 +744,10 @@ impl f16 {
#[inline] #[inline]
#[unstable(feature = "f16", issue = "116909")] #[unstable(feature = "f16", issue = "116909")]
// #[unstable(feature = "float_minimum_maximum", issue = "91079")] // #[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"] #[must_use = "this returns the result of the comparison, without modifying either input"]
pub const fn maximum(self, other: f16) -> f16 { pub const fn maximum(self, other: f16) -> f16 {
#[cfg(not(bootstrap))]
{
intrinsics::maximumf16(self, other) 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
}
}
}
/// Returns the minimum of the two numbers, propagating NaN. /// Returns the minimum of the two numbers, propagating NaN.
/// ///
@@ -792,27 +776,10 @@ impl f16 {
#[inline] #[inline]
#[unstable(feature = "f16", issue = "116909")] #[unstable(feature = "f16", issue = "116909")]
// #[unstable(feature = "float_minimum_maximum", issue = "91079")] // #[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"] #[must_use = "this returns the result of the comparison, without modifying either input"]
pub const fn minimum(self, other: f16) -> f16 { pub const fn minimum(self, other: f16) -> f16 {
#[cfg(not(bootstrap))]
{
intrinsics::minimumf16(self, other) 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
}
}
}
/// Calculates the midpoint (average) between `self` and `rhs`. /// Calculates the midpoint (average) between `self` and `rhs`.
/// ///

View File

@@ -942,26 +942,10 @@ impl f32 {
/// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info. /// 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"] #[must_use = "this returns the result of the comparison, without modifying either input"]
#[unstable(feature = "float_minimum_maximum", issue = "91079")] #[unstable(feature = "float_minimum_maximum", issue = "91079")]
#[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
#[inline] #[inline]
pub const fn maximum(self, other: f32) -> f32 { pub const fn maximum(self, other: f32) -> f32 {
#[cfg(not(bootstrap))]
{
intrinsics::maximumf32(self, other) 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
}
}
}
/// Returns the minimum of the two numbers, propagating NaN. /// Returns the minimum of the two numbers, propagating NaN.
/// ///
@@ -985,27 +969,10 @@ impl f32 {
/// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info. /// 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"] #[must_use = "this returns the result of the comparison, without modifying either input"]
#[unstable(feature = "float_minimum_maximum", issue = "91079")] #[unstable(feature = "float_minimum_maximum", issue = "91079")]
#[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
#[inline] #[inline]
pub const fn minimum(self, other: f32) -> f32 { pub const fn minimum(self, other: f32) -> f32 {
#[cfg(not(bootstrap))]
{
intrinsics::minimumf32(self, other) 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
}
}
}
/// Calculates the midpoint (average) between `self` and `rhs`. /// Calculates the midpoint (average) between `self` and `rhs`.
/// ///

View File

@@ -960,26 +960,10 @@ impl f64 {
/// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info. /// 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"] #[must_use = "this returns the result of the comparison, without modifying either input"]
#[unstable(feature = "float_minimum_maximum", issue = "91079")] #[unstable(feature = "float_minimum_maximum", issue = "91079")]
#[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
#[inline] #[inline]
pub const fn maximum(self, other: f64) -> f64 { pub const fn maximum(self, other: f64) -> f64 {
#[cfg(not(bootstrap))]
{
intrinsics::maximumf64(self, other) 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
}
}
}
/// Returns the minimum of the two numbers, propagating NaN. /// Returns the minimum of the two numbers, propagating NaN.
/// ///
@@ -1003,27 +987,10 @@ impl f64 {
/// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info. /// 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"] #[must_use = "this returns the result of the comparison, without modifying either input"]
#[unstable(feature = "float_minimum_maximum", issue = "91079")] #[unstable(feature = "float_minimum_maximum", issue = "91079")]
#[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
#[inline] #[inline]
pub const fn minimum(self, other: f64) -> f64 { pub const fn minimum(self, other: f64) -> f64 {
#[cfg(not(bootstrap))]
{
intrinsics::minimumf64(self, other) 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
}
}
}
/// Calculates the midpoint (average) between `self` and `rhs`. /// Calculates the midpoint (average) between `self` and `rhs`.
/// ///