You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// 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
-
ifself.is_infinite(){
670
-
// A value may compare unequal to infinity, despite having a "full" exponent mask.
671
-
FpCategory::Infinite
672
-
}elseifself.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.
// 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
-
ifself.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.
0 commit comments