Skip to content

Commit dc69020

Browse files
committed
Add intrinsic fallback for {minimum,maximum}{16,32,64,128}
1 parent e7247df commit dc69020

File tree

5 files changed

+108
-164
lines changed

5 files changed

+108
-164
lines changed

library/core/src/intrinsics/mod.rs

+100-24
Original file line numberDiff line numberDiff line change
@@ -3989,9 +3989,19 @@ pub const fn minnumf128(x: f128, y: f128) -> f128;
39893989
/// Therefore, implementations must not require the user to uphold
39903990
/// any safety invariants.
39913991
#[rustc_nounwind]
3992-
#[rustc_intrinsic]
3993-
#[cfg(not(bootstrap))]
3994-
pub const fn minimumf16(x: f16, y: f16) -> f16;
3992+
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
3993+
pub const fn minimumf16(x: f16, y: f16) -> f16 {
3994+
if x < y {
3995+
x
3996+
} else if y < x {
3997+
y
3998+
} else if x == y {
3999+
if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
4000+
} else {
4001+
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
4002+
x + y
4003+
}
4004+
}
39954005

39964006
/// Returns the minimum (IEEE 754-2019 minimum) of two `f32` values.
39974007
///
@@ -4000,9 +4010,19 @@ pub const fn minimumf16(x: f16, y: f16) -> f16;
40004010
/// Therefore, implementations must not require the user to uphold
40014011
/// any safety invariants.
40024012
#[rustc_nounwind]
4003-
#[rustc_intrinsic]
4004-
#[cfg(not(bootstrap))]
4005-
pub const fn minimumf32(x: f32, y: f32) -> f32;
4013+
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
4014+
pub const fn minimumf32(x: f32, y: f32) -> f32 {
4015+
if x < y {
4016+
x
4017+
} else if y < x {
4018+
y
4019+
} else if x == y {
4020+
if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
4021+
} else {
4022+
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
4023+
x + y
4024+
}
4025+
}
40064026

40074027
/// Returns the minimum (IEEE 754-2019 minimum) of two `f64` values.
40084028
///
@@ -4011,9 +4031,19 @@ pub const fn minimumf32(x: f32, y: f32) -> f32;
40114031
/// Therefore, implementations must not require the user to uphold
40124032
/// any safety invariants.
40134033
#[rustc_nounwind]
4014-
#[rustc_intrinsic]
4015-
#[cfg(not(bootstrap))]
4016-
pub const fn minimumf64(x: f64, y: f64) -> f64;
4034+
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
4035+
pub const fn minimumf64(x: f64, y: f64) -> f64 {
4036+
if x < y {
4037+
x
4038+
} else if y < x {
4039+
y
4040+
} else if x == y {
4041+
if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
4042+
} else {
4043+
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
4044+
x + y
4045+
}
4046+
}
40174047

40184048
/// Returns the minimum (IEEE 754-2019 minimum) of two `f128` values.
40194049
///
@@ -4022,9 +4052,19 @@ pub const fn minimumf64(x: f64, y: f64) -> f64;
40224052
/// Therefore, implementations must not require the user to uphold
40234053
/// any safety invariants.
40244054
#[rustc_nounwind]
4025-
#[rustc_intrinsic]
4026-
#[cfg(not(bootstrap))]
4027-
pub const fn minimumf128(x: f128, y: f128) -> f128;
4055+
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
4056+
pub const fn minimumf128(x: f128, y: f128) -> f128 {
4057+
if x < y {
4058+
x
4059+
} else if y < x {
4060+
y
4061+
} else if x == y {
4062+
if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
4063+
} else {
4064+
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
4065+
x + y
4066+
}
4067+
}
40284068

40294069
/// Returns the maximum (IEEE 754-2008 maxNum) of two `f16` values.
40304070
///
@@ -4087,9 +4127,18 @@ pub const fn maxnumf128(x: f128, y: f128) -> f128;
40874127
/// Therefore, implementations must not require the user to uphold
40884128
/// any safety invariants.
40894129
#[rustc_nounwind]
4090-
#[rustc_intrinsic]
4091-
#[cfg(not(bootstrap))]
4092-
pub const fn maximumf16(x: f16, y: f16) -> f16;
4130+
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
4131+
pub const fn maximumf16(x: f16, y: f16) -> f16 {
4132+
if x > y {
4133+
x
4134+
} else if y > x {
4135+
y
4136+
} else if x == y {
4137+
if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
4138+
} else {
4139+
x + y
4140+
}
4141+
}
40934142

40944143
/// Returns the maximum (IEEE 754-2019 maximum) of two `f32` values.
40954144
///
@@ -4098,9 +4147,18 @@ pub const fn maximumf16(x: f16, y: f16) -> f16;
40984147
/// Therefore, implementations must not require the user to uphold
40994148
/// any safety invariants.
41004149
#[rustc_nounwind]
4101-
#[rustc_intrinsic]
4102-
#[cfg(not(bootstrap))]
4103-
pub const fn maximumf32(x: f32, y: f32) -> f32;
4150+
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
4151+
pub const fn maximumf32(x: f32, y: f32) -> f32 {
4152+
if x > y {
4153+
x
4154+
} else if y > x {
4155+
y
4156+
} else if x == y {
4157+
if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
4158+
} else {
4159+
x + y
4160+
}
4161+
}
41044162

41054163
/// Returns the maximum (IEEE 754-2019 maximum) of two `f64` values.
41064164
///
@@ -4109,9 +4167,18 @@ pub const fn maximumf32(x: f32, y: f32) -> f32;
41094167
/// Therefore, implementations must not require the user to uphold
41104168
/// any safety invariants.
41114169
#[rustc_nounwind]
4112-
#[rustc_intrinsic]
4113-
#[cfg(not(bootstrap))]
4114-
pub const fn maximumf64(x: f64, y: f64) -> f64;
4170+
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
4171+
pub const fn maximumf64(x: f64, y: f64) -> f64 {
4172+
if x > y {
4173+
x
4174+
} else if y > x {
4175+
y
4176+
} else if x == y {
4177+
if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
4178+
} else {
4179+
x + y
4180+
}
4181+
}
41154182

41164183
/// Returns the maximum (IEEE 754-2019 maximum) of two `f128` values.
41174184
///
@@ -4120,9 +4187,18 @@ pub const fn maximumf64(x: f64, y: f64) -> f64;
41204187
/// Therefore, implementations must not require the user to uphold
41214188
/// any safety invariants.
41224189
#[rustc_nounwind]
4123-
#[rustc_intrinsic]
4124-
#[cfg(not(bootstrap))]
4125-
pub const fn maximumf128(x: f128, y: f128) -> f128;
4190+
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
4191+
pub const fn maximumf128(x: f128, y: f128) -> f128 {
4192+
if x > y {
4193+
x
4194+
} else if y > x {
4195+
y
4196+
} else if x == y {
4197+
if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
4198+
} else {
4199+
x + y
4200+
}
4201+
}
41264202

41274203
/// Returns the absolute value of an `f16`.
41284204
///

library/core/src/num/f128.rs

+2-35
Original file line numberDiff line numberDiff line change
@@ -755,25 +755,9 @@ impl f128 {
755755
#[inline]
756756
#[unstable(feature = "f128", issue = "116909")]
757757
// #[unstable(feature = "float_minimum_maximum", issue = "91079")]
758-
#[rustc_const_unstable(feature = "f128", issue = "116909")]
759758
#[must_use = "this returns the result of the comparison, without modifying either input"]
760759
pub const fn maximum(self, other: f128) -> f128 {
761-
#[cfg(not(bootstrap))]
762-
{
763-
intrinsics::maximumf128(self, other)
764-
}
765-
#[cfg(bootstrap)]
766-
{
767-
if self > other {
768-
self
769-
} else if other > self {
770-
other
771-
} else if self == other {
772-
if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
773-
} else {
774-
self + other
775-
}
776-
}
760+
intrinsics::maximumf128(self, other)
777761
}
778762

779763
/// Returns the minimum of the two numbers, propagating NaN.
@@ -804,26 +788,9 @@ impl f128 {
804788
#[inline]
805789
#[unstable(feature = "f128", issue = "116909")]
806790
// #[unstable(feature = "float_minimum_maximum", issue = "91079")]
807-
#[rustc_const_unstable(feature = "f128", issue = "116909")]
808791
#[must_use = "this returns the result of the comparison, without modifying either input"]
809792
pub const fn minimum(self, other: f128) -> f128 {
810-
#[cfg(not(bootstrap))]
811-
{
812-
intrinsics::minimumf128(self, other)
813-
}
814-
#[cfg(bootstrap)]
815-
{
816-
if self < other {
817-
self
818-
} else if other < self {
819-
other
820-
} else if self == other {
821-
if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
822-
} else {
823-
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
824-
self + other
825-
}
826-
}
793+
intrinsics::minimumf128(self, other)
827794
}
828795

829796
/// Calculates the midpoint (average) between `self` and `rhs`.

library/core/src/num/f16.rs

+2-35
Original file line numberDiff line numberDiff line change
@@ -744,25 +744,9 @@ impl f16 {
744744
#[inline]
745745
#[unstable(feature = "f16", issue = "116909")]
746746
// #[unstable(feature = "float_minimum_maximum", issue = "91079")]
747-
#[rustc_const_unstable(feature = "f16", issue = "116909")]
748747
#[must_use = "this returns the result of the comparison, without modifying either input"]
749748
pub const fn maximum(self, other: f16) -> f16 {
750-
#[cfg(not(bootstrap))]
751-
{
752-
intrinsics::maximumf16(self, other)
753-
}
754-
#[cfg(bootstrap)]
755-
{
756-
if self > other {
757-
self
758-
} else if other > self {
759-
other
760-
} else if self == other {
761-
if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
762-
} else {
763-
self + other
764-
}
765-
}
749+
intrinsics::maximumf16(self, other)
766750
}
767751

768752
/// Returns the minimum of the two numbers, propagating NaN.
@@ -792,26 +776,9 @@ impl f16 {
792776
#[inline]
793777
#[unstable(feature = "f16", issue = "116909")]
794778
// #[unstable(feature = "float_minimum_maximum", issue = "91079")]
795-
#[rustc_const_unstable(feature = "f16", issue = "116909")]
796779
#[must_use = "this returns the result of the comparison, without modifying either input"]
797780
pub const fn minimum(self, other: f16) -> f16 {
798-
#[cfg(not(bootstrap))]
799-
{
800-
intrinsics::minimumf16(self, other)
801-
}
802-
#[cfg(bootstrap)]
803-
{
804-
if self < other {
805-
self
806-
} else if other < self {
807-
other
808-
} else if self == other {
809-
if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
810-
} else {
811-
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
812-
self + other
813-
}
814-
}
781+
intrinsics::minimumf16(self, other)
815782
}
816783

817784
/// Calculates the midpoint (average) between `self` and `rhs`.

library/core/src/num/f32.rs

+2-35
Original file line numberDiff line numberDiff line change
@@ -942,25 +942,9 @@ impl f32 {
942942
/// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
943943
#[must_use = "this returns the result of the comparison, without modifying either input"]
944944
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
945-
#[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
946945
#[inline]
947946
pub const fn maximum(self, other: f32) -> f32 {
948-
#[cfg(not(bootstrap))]
949-
{
950-
intrinsics::maximumf32(self, other)
951-
}
952-
#[cfg(bootstrap)]
953-
{
954-
if self > other {
955-
self
956-
} else if other > self {
957-
other
958-
} else if self == other {
959-
if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
960-
} else {
961-
self + other
962-
}
963-
}
947+
intrinsics::maximumf32(self, other)
964948
}
965949

966950
/// Returns the minimum of the two numbers, propagating NaN.
@@ -985,26 +969,9 @@ impl f32 {
985969
/// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
986970
#[must_use = "this returns the result of the comparison, without modifying either input"]
987971
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
988-
#[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
989972
#[inline]
990973
pub const fn minimum(self, other: f32) -> f32 {
991-
#[cfg(not(bootstrap))]
992-
{
993-
intrinsics::minimumf32(self, other)
994-
}
995-
#[cfg(bootstrap)]
996-
{
997-
if self < other {
998-
self
999-
} else if other < self {
1000-
other
1001-
} else if self == other {
1002-
if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
1003-
} else {
1004-
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
1005-
self + other
1006-
}
1007-
}
974+
intrinsics::minimumf32(self, other)
1008975
}
1009976

1010977
/// Calculates the midpoint (average) between `self` and `rhs`.

library/core/src/num/f64.rs

+2-35
Original file line numberDiff line numberDiff line change
@@ -960,25 +960,9 @@ impl f64 {
960960
/// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
961961
#[must_use = "this returns the result of the comparison, without modifying either input"]
962962
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
963-
#[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
964963
#[inline]
965964
pub const fn maximum(self, other: f64) -> f64 {
966-
#[cfg(not(bootstrap))]
967-
{
968-
intrinsics::maximumf64(self, other)
969-
}
970-
#[cfg(bootstrap)]
971-
{
972-
if self > other {
973-
self
974-
} else if other > self {
975-
other
976-
} else if self == other {
977-
if self.is_sign_positive() && other.is_sign_negative() { self } else { other }
978-
} else {
979-
self + other
980-
}
981-
}
965+
intrinsics::maximumf64(self, other)
982966
}
983967

984968
/// Returns the minimum of the two numbers, propagating NaN.
@@ -1003,26 +987,9 @@ impl f64 {
1003987
/// operand is conserved; see the [specification of NaN bit patterns](f32#nan-bit-patterns) for more info.
1004988
#[must_use = "this returns the result of the comparison, without modifying either input"]
1005989
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
1006-
#[rustc_const_unstable(feature = "float_minimum_maximum", issue = "91079")]
1007990
#[inline]
1008991
pub const fn minimum(self, other: f64) -> f64 {
1009-
#[cfg(not(bootstrap))]
1010-
{
1011-
intrinsics::minimumf64(self, other)
1012-
}
1013-
#[cfg(bootstrap)]
1014-
{
1015-
if self < other {
1016-
self
1017-
} else if other < self {
1018-
other
1019-
} else if self == other {
1020-
if self.is_sign_negative() && other.is_sign_positive() { self } else { other }
1021-
} else {
1022-
// At least one input is NaN. Use `+` to perform NaN propagation and quieting.
1023-
self + other
1024-
}
1025-
}
992+
intrinsics::minimumf64(self, other)
1026993
}
1027994

1028995
/// Calculates the midpoint (average) between `self` and `rhs`.

0 commit comments

Comments
 (0)