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

Work around loop identification issues with CBMC #2181

Merged
merged 5 commits into from
Feb 3, 2023

Conversation

celinval
Copy link
Contributor

@celinval celinval commented Feb 2, 2023

Description of changes:

CBMC has a heuristic to identify loops that identifies any jump to a previously declared basic block as the back edge of a loop.

For rust, this happens often due to drop elaboration. See https://rustc-dev-guide.rust-lang.org/mir/drop-elaboration.html#drop-elaboration-1 for more details.

To avoid that issue, we now codegen basic blocks in topological order.

Resolved issues:

Resolves #2164

Related RFC:

Call-outs:

Testing:

  • How is this change tested? New tests

  • Is this a refactor change? No

Checklist

  • Each commit message has a non-empty body, explaining why the change was made
  • Methods or procedures are documented
  • Regression or unit tests are included, or existing tests cover the modified code
  • My PR is restricted to a single feature or bugfix

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

CBMC has a heuristic to identify loops that identifies any jump to a
previously declared basic block as the back edge of a loop.

For rust, this happens often due to drop elaboration. See
https://rustc-dev-guide.rust-lang.org/mir/drop-elaboration.html#drop-elaboration-1
for more details.

To avoid that issue, we now codegen basic blocks in topological order.
@celinval celinval requested a review from a team as a code owner February 2, 2023 22:43
Copy link
Contributor

@tedinski tedinski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Want to add a comment about removing this, with an issue related to the more fundamental CBMC fix? Or should we consider just keeping this change permanently?

@@ -88,7 +89,7 @@ impl<'tcx> GotocCtx<'tcx> {
self.codegen_function_prelude();
self.codegen_declare_variables();

mir.basic_blocks.iter_enumerated().for_each(|(bb, bbd)| self.codegen_block(bb, bbd));
reverse_postorder(mir).for_each(|(bb, bbd)| self.codegen_block(bb, bbd));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sweet.

Copy link
Contributor

@zhassan-aws zhassan-aws left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha! A lot simpler than we thought!

@celinval
Copy link
Contributor Author

celinval commented Feb 2, 2023

Want to add a comment about removing this, with an issue related to the more fundamental CBMC fix? Or should we consider just keeping this change permanently?

I don't see a reason to remove this. I don't think there is any cost here, since rustc caches this information. Even if we have to rerun this, it will be a simple DFS on the basic blocks.

On the plus side, besides working around the CBMC issue, it tends to simplify the CFG for the code we generate which makes it easier to debug later.

It looks like CBMC is no longer able to identify the loop bound and
requires an unwind annotation for this test.

This is a more reasonable behavior than the one this PR fixes, so I'm
going ahead and just updating this harness.
It only fails on linux now, so for the fixme test, I am forcing a
failure on MacOS. For the regular test, we just skip it for Linux.
@celinval celinval merged commit 4178958 into model-checking:main Feb 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Kani fails to verify harness with for loop with bounded iterations
4 participants