Skip to content

Commit 4afc77f

Browse files
author
The Miri Cronjob Bot
committed
Merge from rustc
2 parents a55bf34 + abe63f6 commit 4afc77f

File tree

16 files changed

+845
-901
lines changed

16 files changed

+845
-901
lines changed

core/src/num/f128.rs

-4
Original file line numberDiff line numberDiff line change
@@ -439,10 +439,6 @@ impl f128 {
439439
#[unstable(feature = "f128", issue = "116909")]
440440
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
441441
pub const fn classify(self) -> FpCategory {
442-
// Other float types suffer from various platform bugs that violate the usual IEEE semantics
443-
// and also make bitwise classification not always work reliably. However, `f128` cannot fit
444-
// into any other float types so this is not a concern, and we can rely on bit patterns.
445-
446442
let bits = self.to_bits();
447443
match (bits & Self::MAN_MASK, bits & Self::EXP_MASK) {
448444
(0, Self::EXP_MASK) => FpCategory::Infinite,

core/src/num/f16.rs

+7-36
Original file line numberDiff line numberDiff line change
@@ -424,42 +424,13 @@ impl f16 {
424424
#[unstable(feature = "f16", issue = "116909")]
425425
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
426426
pub const fn classify(self) -> FpCategory {
427-
// A previous implementation for f32/f64 tried to only use bitmask-based checks,
428-
// using `to_bits` to transmute the float to its bit repr and match on that.
429-
// If we only cared about being "technically" correct, that's an entirely legit
430-
// implementation.
431-
//
432-
// Unfortunately, there are platforms out there that do not correctly implement the IEEE
433-
// float semantics Rust relies on: some hardware flushes denormals to zero, and some
434-
// platforms convert to `f32` to perform operations without properly rounding back (e.g.
435-
// WASM, see llvm/llvm-project#96437). These are platforms bugs, and Rust will misbehave on
436-
// such platforms, but we can at least try to make things seem as sane as possible by being
437-
// careful here.
438-
if self.is_infinite() {
439-
// Thus, a value may compare unequal to infinity, despite having a "full" exponent mask.
440-
FpCategory::Infinite
441-
} else if self.is_nan() {
442-
// And it may not be NaN, as it can simply be an "overextended" finite value.
443-
FpCategory::Nan
444-
} else {
445-
// However, std can't simply compare to zero to check for zero, either,
446-
// as correctness requires avoiding equality tests that may be Subnormal == -0.0
447-
// because it may be wrong under "denormals are zero" and "flush to zero" modes.
448-
// Most of std's targets don't use those, but they are used for thumbv7neon.
449-
// So, this does use bitpattern matching for the rest. On x87, due to the incorrect
450-
// float codegen on this hardware, this doesn't actually return a right answer for NaN
451-
// because it cannot correctly discern between a floating point NaN, and some normal
452-
// floating point numbers truncated from an x87 FPU -- but we took care of NaN above, so
453-
// we are fine.
454-
// FIXME(jubilee): This probably could at least answer things correctly for Infinity,
455-
// like the f64 version does, but I need to run more checks on how things go on x86.
456-
// I fear losing mantissa data that would have answered that differently.
457-
let b = self.to_bits();
458-
match (b & Self::MAN_MASK, b & Self::EXP_MASK) {
459-
(0, 0) => FpCategory::Zero,
460-
(_, 0) => FpCategory::Subnormal,
461-
_ => FpCategory::Normal,
462-
}
427+
let b = self.to_bits();
428+
match (b & Self::MAN_MASK, b & Self::EXP_MASK) {
429+
(0, Self::EXP_MASK) => FpCategory::Infinite,
430+
(_, Self::EXP_MASK) => FpCategory::Nan,
431+
(0, 0) => FpCategory::Zero,
432+
(_, 0) => FpCategory::Subnormal,
433+
_ => FpCategory::Normal,
463434
}
464435
}
465436

core/src/num/f32.rs

+12-39
Original file line numberDiff line numberDiff line change
@@ -652,45 +652,18 @@ impl f32 {
652652
#[stable(feature = "rust1", since = "1.0.0")]
653653
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
654654
pub const fn classify(self) -> FpCategory {
655-
// A previous implementation tried to only use bitmask-based checks,
656-
// using f32::to_bits to transmute the float to its bit repr and match on that.
657-
// If we only cared about being "technically" correct, that's an entirely legit
658-
// implementation.
659-
//
660-
// Unfortunately, there is hardware out there that does not correctly implement the IEEE
661-
// float semantics Rust relies on: x87 uses a too-large mantissa and exponent, and some
662-
// hardware flushes subnormals to zero. These are platforms bugs, and Rust will misbehave on
663-
// such hardware, but we can at least try to make things seem as sane as possible by being
664-
// careful here.
665-
//
666-
// FIXME(jubilee): Using x87 operations is never necessary in order to function
667-
// on x86 processors for Rust-to-Rust calls, so this issue should not happen.
668-
// Code generation should be adjusted to use non-C calling conventions, avoiding this.
669-
if self.is_infinite() {
670-
// A value may compare unequal to infinity, despite having a "full" exponent mask.
671-
FpCategory::Infinite
672-
} else if self.is_nan() {
673-
// And it may not be NaN, as it can simply be an "overextended" finite value.
674-
FpCategory::Nan
675-
} else {
676-
// However, std can't simply compare to zero to check for zero, either,
677-
// as correctness requires avoiding equality tests that may be Subnormal == -0.0
678-
// because it may be wrong under "denormals are zero" and "flush to zero" modes.
679-
// Most of std's targets don't use those, but they are used for thumbv7neon.
680-
// So, this does use bitpattern matching for the rest. On x87, due to the incorrect
681-
// float codegen on this hardware, this doesn't actually return a right answer for NaN
682-
// because it cannot correctly discern between a floating point NaN, and some normal
683-
// floating point numbers truncated from an x87 FPU -- but we took care of NaN above, so
684-
// we are fine.
685-
// FIXME(jubilee): This probably could at least answer things correctly for Infinity,
686-
// like the f64 version does, but I need to run more checks on how things go on x86.
687-
// I fear losing mantissa data that would have answered that differently.
688-
let b = self.to_bits();
689-
match (b & Self::MAN_MASK, b & Self::EXP_MASK) {
690-
(0, 0) => FpCategory::Zero,
691-
(_, 0) => FpCategory::Subnormal,
692-
_ => FpCategory::Normal,
693-
}
655+
// We used to have complicated logic here that avoids the simple bit-based tests to work
656+
// around buggy codegen for x87 targets (see
657+
// https://github.com/rust-lang/rust/issues/114479). However, some LLVM versions later, none
658+
// of our tests is able to find any difference between the complicated and the naive
659+
// version, so now we are back to the naive version.
660+
let b = self.to_bits();
661+
match (b & Self::MAN_MASK, b & Self::EXP_MASK) {
662+
(0, Self::EXP_MASK) => FpCategory::Infinite,
663+
(_, Self::EXP_MASK) => FpCategory::Nan,
664+
(0, 0) => FpCategory::Zero,
665+
(_, 0) => FpCategory::Subnormal,
666+
_ => FpCategory::Normal,
694667
}
695668
}
696669

core/src/num/f64.rs

+12-35
Original file line numberDiff line numberDiff line change
@@ -651,41 +651,18 @@ impl f64 {
651651
#[stable(feature = "rust1", since = "1.0.0")]
652652
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
653653
pub const fn classify(self) -> FpCategory {
654-
// A previous implementation tried to only use bitmask-based checks,
655-
// using f64::to_bits to transmute the float to its bit repr and match on that.
656-
// If we only cared about being "technically" correct, that's an entirely legit
657-
// implementation.
658-
//
659-
// Unfortunately, there is hardware out there that does not correctly implement the IEEE
660-
// float semantics Rust relies on: x87 uses a too-large exponent, and some hardware flushes
661-
// subnormals to zero. These are platforms bugs, and Rust will misbehave on such hardware,
662-
// but we can at least try to make things seem as sane as possible by being careful here.
663-
//
664-
// FIXME(jubilee): Using x87 operations is never necessary in order to function
665-
// on x86 processors for Rust-to-Rust calls, so this issue should not happen.
666-
// Code generation should be adjusted to use non-C calling conventions, avoiding this.
667-
//
668-
// Thus, a value may compare unequal to infinity, despite having a "full" exponent mask.
669-
// And it may not be NaN, as it can simply be an "overextended" finite value.
670-
if self.is_nan() {
671-
FpCategory::Nan
672-
} else {
673-
// However, std can't simply compare to zero to check for zero, either,
674-
// as correctness requires avoiding equality tests that may be Subnormal == -0.0
675-
// because it may be wrong under "denormals are zero" and "flush to zero" modes.
676-
// Most of std's targets don't use those, but they are used for thumbv7neon.
677-
// So, this does use bitpattern matching for the rest. On x87, due to the incorrect
678-
// float codegen on this hardware, this doesn't actually return a right answer for NaN
679-
// because it cannot correctly discern between a floating point NaN, and some normal
680-
// floating point numbers truncated from an x87 FPU -- but we took care of NaN above, so
681-
// we are fine.
682-
let b = self.to_bits();
683-
match (b & Self::MAN_MASK, b & Self::EXP_MASK) {
684-
(0, Self::EXP_MASK) => FpCategory::Infinite,
685-
(0, 0) => FpCategory::Zero,
686-
(_, 0) => FpCategory::Subnormal,
687-
_ => FpCategory::Normal,
688-
}
654+
// We used to have complicated logic here that avoids the simple bit-based tests to work
655+
// around buggy codegen for x87 targets (see
656+
// https://github.com/rust-lang/rust/issues/114479). However, some LLVM versions later, none
657+
// of our tests is able to find any difference between the complicated and the naive
658+
// version, so now we are back to the naive version.
659+
let b = self.to_bits();
660+
match (b & Self::MAN_MASK, b & Self::EXP_MASK) {
661+
(0, Self::EXP_MASK) => FpCategory::Infinite,
662+
(_, Self::EXP_MASK) => FpCategory::Nan,
663+
(0, 0) => FpCategory::Zero,
664+
(_, 0) => FpCategory::Subnormal,
665+
_ => FpCategory::Normal,
689666
}
690667
}
691668

0 commit comments

Comments
 (0)