Skip to content

[5.6] Fix misoptimization in OptimizeHopToExecutor #41176

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

Merged
merged 1 commit into from
Feb 4, 2022

Conversation

kavon
Copy link
Member

@kavon kavon commented Feb 3, 2022

Explanation: A misoptimization of Swift concurrency features (hop_to_executor) can lead to incorrect runtime behavior, where actor isolation is not actually gained, which can lead to data races, etc.
Scope: Difficult to estimate, but large enough to have received one bug report from a user. The conditions in which the misoptimization will trigger are not easy to describe in terms of the Swift language. That's because very inoccuous source changes can perturb the code generation enough to hide or show the misoptimization. Since the errant optimization pass is always run, all programs using Swift Concurrency are at risk. A change that would make this misoptimization more likely to happen landed for Swift 5.6 recently, so it's only likely to get worse.
Radar/SR Issue: rdar://88285600
Risk: Extremely low.
Testing: PR testing and CI .
Reviewed By: Doug Gregor and Erik Eckstein
Original PR: #41175

@kavon kavon requested a review from a team as a code owner February 3, 2022 03:28
@kavon
Copy link
Member Author

kavon commented Feb 3, 2022

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Feb 3, 2022

Build failed
Swift Test Linux Platform
Git Sha - 53f52bfc5a4f98311ea2a07f974358aaa123937c

@swift-ci
Copy link
Contributor

swift-ci commented Feb 3, 2022

Build failed
Swift Test OS X Platform
Git Sha - 53f52bfc5a4f98311ea2a07f974358aaa123937c

The problem is in `OptimizeHopToExecutor::collectActors`, which is
causing `removeRedundantHopToExecutors` to drop the `hop_to_executor`. The issue
is triggered by the order in which the Actors map is populated, and the reuse
of a SILValue representing an executor. Suppose we have a function like this:

```
bb0:
  %7 = builtin "getCurrentExecutor"() : $Optional<Builtin.Executor>
  // ...
  cond_br %12, bb2, bb1

bb1:
  // ...
  hop_to_executor %7 : $Optional<Builtin.Executor>

bb2:
  // ...
  hop_to_executor %7 : $Optional<Builtin.Executor>
  // ...
  hop_to_executor %28 : $MainActor
```

Since `collectActors` goes through each function's instructions top-down,
and assigns to each unique SILValue an ID equal to the size of the Actors map
prior to inserting the SILValue in the map, and we end up with the wrong actor IDs.

This commit changes the ID numbering scheme to correct the issue.
@kavon
Copy link
Member Author

kavon commented Feb 3, 2022

@swift-ci please test

@kavon
Copy link
Member Author

kavon commented Feb 3, 2022

@swift-ci please nominate

1 similar comment
@DougGregor
Copy link
Member

@swift-ci please nominate

@DougGregor DougGregor merged commit 45fa618 into swiftlang:release/5.6 Feb 4, 2022
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.

3 participants