-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[DynamicCast] Rely on runtime when casts can't be optimized #33761
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
[DynamicCast] Rely on runtime when casts can't be optimized #33761
Conversation
@swift-ci Please test |
Build failed |
Build failed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. We shouldn't try to peephole these in IRGen; we should let the cast optimizer do that if possible.
@swift-ci Please test macOS |
Build failed |
@swift-ci Please test |
Build failed |
Build failed |
Looks like the Linux test is failing in optimized builds due to some issue with ARC. I'm trying to isolate whether it's an issue with my change or is an existing bug in the compiler ARC optimizations. |
Thanks to @eeckstein for fixing the ARC bug I was tripping over. Now let's try those tests again! |
@swift-ci Please test |
Build failed |
Linux is crashing on the optimized form of this test:
|
@swift-ci Please test Linux |
Re-ran the full Linux test locally and it's passing for me. Hmmm.... I'll try the CI bot again and see if that still fails before I spend time digging further. |
Build failed |
Re-ran the Linux test locally on Ubuntu 16.04 (required upgrading clang-3.8 to clang-12), and it all passes just fine. I guess I'll try again with the CI preset and see?? |
Still having trouble reproducing this locally. I'll try again with the exact build options used on the CI bot. |
1f2335d
to
e5381bd
Compare
@swift-ci Please test |
Build failed |
e5381bd
to
318935e
Compare
@swift-ci Please test |
Let's see if the test that's been failing on Linux also fails on macOS when you enable it properly. |
Build failed |
Same cast was in a disabled test in Casts.swift, so I also enabled that unconditionally. With that, I can now consistently reproduce it on Linux. The root cause seems to be another variation of the ARC issue that @eeckstein fixed for me earlier. As before, it fails on Linux because it triggers |
4c3818b
to
543d4fc
Compare
I believe #34383 will resolve the last test failure here. |
Build failed |
The Swift compiler renders `as?` operations in Swift into variations of the `checked_cast_br` instructions in SIL. Subsequent optimization passes may alter or eliminate these instructions. Any remaining instructions after optimization are translated by IRGen into runtime calls. At least, that's the theory. Unfortunately, the current IRGen logic does not recognize all of the casting instruction variants and renders one particular unrecognized variant as a simple nil load. Specifically, this occurs for optimized casts of metatypes to AnyObject: ``` let a = Int.self let b = a as? AnyObject // b should not be nil here ``` This PR changes this case in IRGen to instead generate a call to `swift_dynamicCast`, deferring this case to the runtime. Future: Someday, the compiler should be taught to correctly optimize this cast away.
I think this exercises the same optimizer path that's breaking another test I've been staring at.
543d4fc
to
35aa75a
Compare
Now that #34383 has landed, let's try this again. |
@swift-ci Please test |
Build failed |
@swift-ci Please clean test Linux |
* 'main' of github.com:apple/swift: [DynamicCast] Rely on runtime when casts can't be optimized (swiftlang#33761)
The Swift compiler renders
as?
operations in Swift into variations of thechecked_cast_br
instructions in SIL. Subsequent optimization passes may alter or eliminate these instructions. Any remaining cast instructions after optimization are translated by IRGen into runtime calls.At least, that's the theory. Unfortunately, the current IRGen logic does not recognize all of the casting instruction variants and translates one particular unrecognized variant into a simple nil load. This effectively converts an
as?
operation into one that will always fail. Specifically, this occurs for optimized casts of metatypes to AnyObject:(Ironically, in this particular case, the frontend issues a diagnostic warning that the cast will always succeed.)
This PR changes this case in IRGen to instead generate a call to
swift_dynamicCast
, deferring this case to the runtime. (Yes, this particular example should get optimized into a simple store, but that's a future project.)Test suite changes:
checked_cast_br
instruction with a thin metatype. The IRGen pass should never see instructions of this form, so I've changed that particular test to exercise a thick metatype instead.