Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enable const-float-classify test, and test_next_up/down on 32bit x86 #129835

Merged
merged 4 commits into from
Sep 12, 2024

Conversation

RalfJung
Copy link
Member

The test_next_up/down tests have been disabled on all 32bit x86 targets, which goes too far -- they should definitely work on our (tier 1) i686 target, it is only without SSE that we might run into trouble due to #114479. However, I cannot reproduce that trouble any more -- maybe that got fixed by #123351?

The const-float-classify test relied on const traits "because we can", and got disabled when const traits got removed. That's an unfortunate reduction in test coverage of our float functionality, so let's restore the test in a way that does not rely on const traits.

The const-float tests are actually testing runtime behavior as well, and I don't think that runtime behavior is covered anywhere else. Probably they shouldn't be called "const-float", but we don't have a tests/ui/float folder... should I create one and move them there? Are there any other ui tests that should be moved there?

I also removed some FIXME referring to not use x87 for Rust-to-Rust-calls -- that has happened in #123351 so this got fixed indeed. Does that mean we can simplify all that float code again? I am not sure how to test it. Is running the test suite with an i586 target enough?

Cc @tgross35 @workingjubilee

@rustbot
Copy link
Collaborator

rustbot commented Aug 31, 2024

r? @Nadrieril

rustbot has assigned @Nadrieril.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 31, 2024
@RalfJung
Copy link
Member Author

I tried this diff:

diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 4c089946033..ca2205d38e1 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -662,13 +662,7 @@ pub const fn classify(self) -> FpCategory {
         // hardware flushes subnormals to zero. These are platforms bugs, and Rust will misbehave on
         // such hardware, but we can at least try to make things seem as sane as possible by being
         // careful here.
-        if self.is_infinite() {
-            // A value may compare unequal to infinity, despite having a "full" exponent mask.
-            FpCategory::Infinite
-        } else if self.is_nan() {
-            // And it may not be NaN, as it can simply be an "overextended" finite value.
-            FpCategory::Nan
-        } else {
+        {
             // However, std can't simply compare to zero to check for zero, either,
             // as correctness requires avoiding equality tests that may be Subnormal == -0.0
             // because it may be wrong under "denormals are zero" and "flush to zero" modes.
@@ -683,6 +677,8 @@ pub const fn classify(self) -> FpCategory {
             // I fear losing mantissa data that would have answered that differently.
             let b = self.to_bits();
             match (b & Self::MAN_MASK, b & Self::EXP_MASK) {
+                (0, Self::EXP_MASK) => FpCategory::Infinite,
+                (_, Self::EXP_MASK) => FpCategory::Nan,
                 (0, 0) => FpCategory::Zero,
                 (_, 0) => FpCategory::Subnormal,
                 _ => FpCategory::Normal,
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index bcef8fe7724..b5ef9e85aac 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -663,9 +663,7 @@ pub const fn classify(self) -> FpCategory {
         //
         // Thus, a value may compare unequal to infinity, despite having a "full" exponent mask.
         // And it may not be NaN, as it can simply be an "overextended" finite value.
-        if self.is_nan() {
-            FpCategory::Nan
-        } else {
+        {
             // However, std can't simply compare to zero to check for zero, either,
             // as correctness requires avoiding equality tests that may be Subnormal == -0.0
             // because it may be wrong under "denormals are zero" and "flush to zero" modes.
@@ -678,6 +676,7 @@ pub const fn classify(self) -> FpCategory {
             let b = self.to_bits();
             match (b & Self::MAN_MASK, b & Self::EXP_MASK) {
                 (0, Self::EXP_MASK) => FpCategory::Infinite,
+                (_, Self::EXP_MASK) => FpCategory::Nan,
                 (0, 0) => FpCategory::Zero,
                 (_, 0) => FpCategory::Subnormal,
                 _ => FpCategory::Normal,

And the tests seem to still pass. But I am not sure if there are more tests you ran, @workingjubilee ? Is it worth trying the bit-based classify implementation again?

I think I'll rather not touch this code for now.^^

@tgross35
Copy link
Contributor

tgross35 commented Sep 1, 2024

The test_next_up/down tests have been disabled on all 32bit x86 targets, which goes too far -- they should definitely work on our (tier 1) i686 target, it is only without SSE that we might run into trouble due to #114479. However, I cannot reproduce that trouble any more -- maybe that got fixed by #123351?

Could a similar test be tried making sure the calls are extern "C"? I suspect that #123351 did fix things for the default ABI, but it left C untouched.

@tgross35
Copy link
Contributor

tgross35 commented Sep 1, 2024

The const-float tests are actually testing runtime behavior as well, and I don't think that runtime behavior is covered anywhere else. Probably they shouldn't be called "const-float", but we don't have a tests/ui/float folder... should I create one and move them there? Are there any other ui tests that should be moved there?

I don't really know what a good solution is here. We have a ton of float tests that are quite similar but slightly different, spread out in a bunch of different locations - std tests, UI tests, miri, compiler_builtins, etc. Even the pattern generation we have at https://github.com/rust-lang/rust/tree/a7399ba69d37b019677a9c47fe89ceb8dd82db2d/src/etc/test-float-parse now would be pretty useful for making sure the edge cases are checked.

I know that is entirely unhelpful, just thinking it would be nice if we had a single suite we could run against both const and runtime somehow.

@RalfJung
Copy link
Member Author

RalfJung commented Sep 1, 2024

Could a similar test be tried making sure the calls are extern "C"? I suspect that #123351 did fix things for the default ABI, but it left C untouched.

This calls a bunch of Rust functions though so the Rust ABI is what we want. What would be the point of using the C ABI here? We know that one is broken...

@tgross35
Copy link
Contributor

tgross35 commented Sep 1, 2024

Ah, I thought you were still trying to work around the fix to repro the behavior that led to these notes.

@RalfJung
Copy link
Member Author

RalfJung commented Sep 1, 2024

I tried adding extern "C" to from_bits, next_up, next_down -- that made no difference.

So yeah not sure how to reproduce the failures. I guess we should do a try-build of the relevant runner. Time to figure out how that works...

@rustbot rustbot added A-testsuite Area: The testsuite used to check the correctness of rustc T-infra Relevant to the infrastructure team, which will review and decide on the PR/issue. labels Sep 1, 2024
@RalfJung
Copy link
Member Author

RalfJung commented Sep 1, 2024

These tests seem to have been disabled on x86 since they got added: #100578. And that goes back to this CI failure. So we should be seeing it on CI if it's still a problem.

@RalfJung
Copy link
Member Author

RalfJung commented Sep 1, 2024

But the tests passed on CI. So... maybe something changed in LLVM that makes this less of a problem in practice?

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@RalfJung
Copy link
Member Author

RalfJung commented Sep 1, 2024

The job passed, and then the "dist" part failed of course.

So... something else must have changed to make the text_up/down stuff work on x87 now, and even make d6ea15a work.

@workingjubilee how did you test the classify stuff? Do you have a setup that can reproduce a failure when one does "naive" bit-based classification?

@RalfJung
Copy link
Member Author

RalfJung commented Sep 1, 2024

Anyway that seems orthogonal to this PR -- test_next_up/down were disabled on x86 because they failed on CI; they no longer fail on CI; that should be sufficient to enable these tests again.

@RalfJung RalfJung force-pushed the float-tests branch 2 times, most recently from d61345b to cc38581 Compare September 1, 2024 12:29
@workingjubilee
Copy link
Member

@RalfJung I have rebased your PR, I hope that's okay.

@workingjubilee
Copy link
Member

workingjubilee commented Sep 10, 2024

As a minor note, it's very important to make "moving some files around" and "changing those files" as separate commits because "diffing files against the previous state and noticing some are very similar" is exactly how git notices some files moved. That's why in the process of rebasing this PR I introduced a pure "movement only" commit.

@rust-log-analyzer

This comment has been minimized.

RalfJung and others added 2 commits September 10, 2024 16:47
- remove an outdated FIXME
- add reference to floating-point semantics issue

Co-authored-by: Jubilee <[email protected]>
@workingjubilee
Copy link
Member

@bors r+

@bors
Copy link
Contributor

bors commented Sep 11, 2024

📌 Commit e556c13 has been approved by workingjubilee

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Sep 11, 2024
@RalfJung
Copy link
Member Author

As a minor note, it's very important to make "moving some files around" and "changing those files" as separate commits because "diffing files against the previous state and noticing some are very similar" is exactly how git notices some files moved. That's why in the process of rebasing this PR I introduced a pure "movement only" commit.

Yeah, sorry for that... move + small changes usually works fine but then the changes became bigger and bigger.

workingjubilee added a commit to workingjubilee/rustc that referenced this pull request Sep 11, 2024
…ilee

enable const-float-classify test, and test_next_up/down on 32bit x86

The  test_next_up/down tests have been disabled on all 32bit x86 targets, which goes too far -- they should definitely work on our (tier 1) i686 target, it is only without SSE that we might run into trouble due to rust-lang#114479. However, I cannot reproduce that trouble any more -- maybe that got fixed by rust-lang#123351?

The  const-float-classify test relied on const traits "because we can", and got disabled when const traits got removed. That's an unfortunate reduction in test coverage of our float functionality, so let's restore the test in a way that does not rely on const traits.

The const-float tests are actually testing runtime behavior as well, and I don't think that runtime behavior is covered anywhere else. Probably they shouldn't be called "const-float", but we don't have a `tests/ui/float` folder... should I create one and move them there? Are there any other ui tests that should be moved there?

I also removed some FIXME referring to not use x87 for Rust-to-Rust-calls -- that has happened in rust-lang#123351 so this got fixed indeed. Does that mean we can simplify all that float code again? I am not sure how to test it. Is running the test suite with an i586 target enough?

Cc `@tgross35` `@workingjubilee`
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 11, 2024
…kingjubilee

Rollup of 14 pull requests

Successful merges:

 - rust-lang#129260 (Don't suggest adding return type for closures with default return type)
 - rust-lang#129520 (Suggest the correct pattern syntax on usage of unit variant pattern for a struct variant)
 - rust-lang#129696 (update stdarch)
 - rust-lang#129759 (Stabilize `const_refs_to_static`)
 - rust-lang#129835 (enable const-float-classify test, and test_next_up/down on 32bit x86)
 - rust-lang#129866 (Clarify documentation labelling and definitions for std::collections)
 - rust-lang#130052 (Don't leave debug locations for constants sitting on the builder indefinitely)
 - rust-lang#130077 (Fix linking error when compiling for 32-bit watchOS)
 - rust-lang#130123 (Report the `note` when specified in `diagnostic::on_unimplemented`)
 - rust-lang#130156 (Add test for S_OBJNAME & update test for LF_BUILDINFO cl and cmd)
 - rust-lang#130206 (Map `WSAEDQUOT` to `ErrorKind::FilesystemQuotaExceeded`)
 - rust-lang#130207 (Map `ERROR_CANT_RESOLVE_FILENAME` to `ErrorKind::FilesystemLoop`)
 - rust-lang#130219 (Fix false positive with `missing_docs` and `#[test]`)
 - rust-lang#130221 (Make SearchPath::new public)

r? `@ghost`
`@rustbot` modify labels: rollup
workingjubilee added a commit to workingjubilee/rustc that referenced this pull request Sep 11, 2024
…ilee

enable const-float-classify test, and test_next_up/down on 32bit x86

The  test_next_up/down tests have been disabled on all 32bit x86 targets, which goes too far -- they should definitely work on our (tier 1) i686 target, it is only without SSE that we might run into trouble due to rust-lang#114479. However, I cannot reproduce that trouble any more -- maybe that got fixed by rust-lang#123351?

The  const-float-classify test relied on const traits "because we can", and got disabled when const traits got removed. That's an unfortunate reduction in test coverage of our float functionality, so let's restore the test in a way that does not rely on const traits.

The const-float tests are actually testing runtime behavior as well, and I don't think that runtime behavior is covered anywhere else. Probably they shouldn't be called "const-float", but we don't have a `tests/ui/float` folder... should I create one and move them there? Are there any other ui tests that should be moved there?

I also removed some FIXME referring to not use x87 for Rust-to-Rust-calls -- that has happened in rust-lang#123351 so this got fixed indeed. Does that mean we can simplify all that float code again? I am not sure how to test it. Is running the test suite with an i586 target enough?

Cc ``@tgross35`` ``@workingjubilee``
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 11, 2024
…kingjubilee

Rollup of 11 pull requests

Successful merges:

 - rust-lang#119286 (show linker output even if the linker succeeds)
 - rust-lang#129103 (Don't warn empty branches unreachable for now)
 - rust-lang#129696 (update stdarch)
 - rust-lang#129835 (enable const-float-classify test, and test_next_up/down on 32bit x86)
 - rust-lang#129992 (Update compiler-builtins to 0.1.125)
 - rust-lang#130052 (Don't leave debug locations for constants sitting on the builder indefinitely)
 - rust-lang#130077 (Fix linking error when compiling for 32-bit watchOS)
 - rust-lang#130114 (Remove needless returns detected by clippy in the compiler)
 - rust-lang#130156 (Add test for S_OBJNAME & update test for LF_BUILDINFO cl and cmd)
 - rust-lang#130168 (maint: update docs for change_time ext and doc links)
 - rust-lang#130239 (miri: fix overflow detection for unsigned pointer offset)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 11, 2024
…kingjubilee

Rollup of 10 pull requests

Successful merges:

 - rust-lang#129103 (Don't warn empty branches unreachable for now)
 - rust-lang#129696 (update stdarch)
 - rust-lang#129835 (enable const-float-classify test, and test_next_up/down on 32bit x86)
 - rust-lang#130077 (Fix linking error when compiling for 32-bit watchOS)
 - rust-lang#130114 (Remove needless returns detected by clippy in the compiler)
 - rust-lang#130168 (maint: update docs for change_time ext and doc links)
 - rust-lang#130228 (notify Miri when intrinsics are changed)
 - rust-lang#130239 (miri: fix overflow detection for unsigned pointer offset)
 - rust-lang#130244 (Use the same span for attributes and Try expansion of ?)
 - rust-lang#130248 (Limit `libc::link` usage to `nto70` target only, not NTO OS)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 312b597 into rust-lang:master Sep 12, 2024
6 checks passed
@rustbot rustbot added this to the 1.83.0 milestone Sep 12, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Sep 12, 2024
Rollup merge of rust-lang#129835 - RalfJung:float-tests, r=workingjubilee

enable const-float-classify test, and test_next_up/down on 32bit x86

The  test_next_up/down tests have been disabled on all 32bit x86 targets, which goes too far -- they should definitely work on our (tier 1) i686 target, it is only without SSE that we might run into trouble due to rust-lang#114479. However, I cannot reproduce that trouble any more -- maybe that got fixed by rust-lang#123351?

The  const-float-classify test relied on const traits "because we can", and got disabled when const traits got removed. That's an unfortunate reduction in test coverage of our float functionality, so let's restore the test in a way that does not rely on const traits.

The const-float tests are actually testing runtime behavior as well, and I don't think that runtime behavior is covered anywhere else. Probably they shouldn't be called "const-float", but we don't have a `tests/ui/float` folder... should I create one and move them there? Are there any other ui tests that should be moved there?

I also removed some FIXME referring to not use x87 for Rust-to-Rust-calls -- that has happened in rust-lang#123351 so this got fixed indeed. Does that mean we can simplify all that float code again? I am not sure how to test it. Is running the test suite with an i586 target enough?

Cc ```@tgross35``` ```@workingjubilee```
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 14, 2024
simplify float::classify logic

I played around with the float-classify test in the hope of triggering x87 bugs by strategically adding `black_box`, and still the exact expression `@beetrees` suggested [here](rust-lang#129835 (comment)) remains the only case I found where we get the wrong result on x87. Curiously, this bug only occurs when MIR optimizations are enabled -- probably the extra inlining that does is required for LLVM to hit the right "bad" case in the backend. But even for that case, it makes no difference whether `classify` is implemented in the simple bit-pattern-based version or the more complicated version we had before.

Without even a single testcase that can distinguish our `classify` from the naive version, I suggest we switch to the naive version.

try-job: armhf-gnu
try-job: dist-armv7-linux
try-job: i686-msvc
try-job: i686-mingw
try-job: test-various
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 15, 2024
…bilee

simplify float::classify logic

I played around with the float-classify test in the hope of triggering x87 bugs by strategically adding `black_box`, and still the exact expression `@beetrees` suggested [here](rust-lang#129835 (comment)) remains the only case I found where we get the wrong result on x87. Curiously, this bug only occurs when MIR optimizations are enabled -- probably the extra inlining that does is required for LLVM to hit the right "bad" case in the backend. But even for that case, it makes no difference whether `classify` is implemented in the simple bit-pattern-based version or the more complicated version we had before.

Without even a single testcase that can distinguish our `classify` from the naive version, I suggest we switch to the naive version.
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 16, 2024
…bilee

simplify float::classify logic

I played around with the float-classify test in the hope of triggering x87 bugs by strategically adding `black_box`, and still the exact expression `@beetrees` suggested [here](rust-lang#129835 (comment)) remains the only case I found where we get the wrong result on x87. Curiously, this bug only occurs when MIR optimizations are enabled -- probably the extra inlining that does is required for LLVM to hit the right "bad" case in the backend. But even for that case, it makes no difference whether `classify` is implemented in the simple bit-pattern-based version or the more complicated version we had before.

Without even a single testcase that can distinguish our `classify` from the naive version, I suggest we switch to the naive version.
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Sep 17, 2024
simplify float::classify logic

I played around with the float-classify test in the hope of triggering x87 bugs by strategically adding `black_box`, and still the exact expression `@beetrees` suggested [here](rust-lang/rust#129835 (comment)) remains the only case I found where we get the wrong result on x87. Curiously, this bug only occurs when MIR optimizations are enabled -- probably the extra inlining that does is required for LLVM to hit the right "bad" case in the backend. But even for that case, it makes no difference whether `classify` is implemented in the simple bit-pattern-based version or the more complicated version we had before.

Without even a single testcase that can distinguish our `classify` from the naive version, I suggest we switch to the naive version.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-testsuite Area: The testsuite used to check the correctness of rustc S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-infra Relevant to the infrastructure team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants