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
[SR-11010] Swift 5.1 infinite compile with optimizations #53400
Comments
Hm, did not reproduce for me in an isolated command-line build. Can you attach a project, so that we know we're seeing the same thing? |
Sorry I changed my example back from `if` -> `while`, there seems to be some flakiness here so I thought that worked but maybe it didn't, can you try with that example? |
Okay, that one reproduces! AppKit version for easier testing:
|
Probably expected but still repros the same way with Xcode 11 beta 3 |
Maybe you can pass `-Xllvm -sil-disable-pass=jumpthread-simplify-cfg` to get around the issue in the meantime. |
It looks like in this case that flag doesn't help |
Looks like this still repros with beta 4, @belkadan do you know if this is on anyone's radar to fix? |
I can't really talk about what people are and aren't working on if they haven't done anything publicly yet, sorry. |
I have a fix here for the infinite loop in the compiler, but be aware if the hit test returns none, this is semantically an infinite loop. If one expands out the pattern matching, since hitTest returns an optional, the while loop condition is actually: ![(view != nil) && (view! is UIView)] This simplifies down to: (view == nil) || !(view! is UIView) If we plug that into our example, we get: class SomeView: UIView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
var view: UIView? = super.hitTest(.zero, with: nil)
while (view == nil) || !(view! is UIView) {
guard let v: UIView = view else { continue }
view = v.superview
}
return nil
}
} Notice how this means that if view is nil, we get an infinite loop. Interestingly, when we hit the bug in simplify CFG, the compiler has already simplified this more by eliminating the cast. class SomeView: UIView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
var view: UIView? = super.hitTest(.zero, with: nil)
while view == nil {
guard let v: UIView = view else { continue }
view = v.superview
}
return nil
}
} and then propagating the view == nil information into the while loop: class SomeView: UIView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
var view: UIView? = super.hitTest(.zero, with: nil)
while view == nil {
continue
}
return nil
}
} I imagine that isn't what you intended. Is this code you are actually using? Or was this just a code twiddle that you did not expect to work at runtime, but did expect the compiler not infinite loop on. |
Thanks! Yea it looks like it was some dead code, but I do think because of other implementation details from our case that I simplified out this wouldn't have actually ever resulted in an infinite loop |
Looks like Michael forgot to move this to Done. It should be in 5.1 and master by now, though not any Xcode yet. |
Yes. Thanks! |
Environment
Xcode 11 beta 2 11M337n
macOS 10.14.5 18F203
Additional Detail from JIRA
md5: e0eb50be50322b3745bb13f5fad4762b
Issue Description:
With Swift 5.1 and this code:
If you build it with:
The build never completes (I waited 70 minutes on my non-reduced case before cancelling). If you remove the `-O` it completes as expected. During this time swift also consumes 100% CPU. Here's a sample during this time:
The text was updated successfully, but these errors were encountered: