-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[IRGen] Handle tuple return types with function signature for LoadableByAddress transformation. #17545
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
Conversation
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.
Just a couple of minor comments here. This really should be reviewed by @shajrawi
@@ -0,0 +1,33 @@ | |||
// RUN: %target-swift-frontend %s -emit-ir | |||
|
|||
import Foundation |
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.
I think this is unnecessary. There are no Foundation types used below
@@ -0,0 +1,33 @@ | |||
// RUN: %target-swift-frontend %s -emit-ir |
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.
Maybe this should go into test/IRGen/big_types_corner_cases.swift?
Thank you, Slava. I updated the test as per your comments. |
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.
This bug fix is incorrect. If you run the test-case you added with -sil-verify-all you can see it crashing:
SIL verification failed: normal destination of try_apply must take argument of normal result type
$Optional<@callee_guaranteed (@in_guaranteed Change) -> Bool>
$Optional<@callee_guaranteed (@guaranteed Change) -> Bool>
Verifying instruction:
%0 = argument of bb0 : $*Q.Returned // user: %34
%1 = argument of bb0 : $*Q // users: %34, %108, %5
%29 = argument of bb5 : $@callee_guaranteed (@in_guaranteed Q) -> (@out Q.Returned, @owned Optional<@callee_guaranteed (@guaranteed Change) -> Bool>, @error Error) // users: %34, %139, %138, %37, %36, %33, %30
-> try_apply %29(%0, %1) : $@callee_guaranteed (@in_guaranteed Q) -> (@out Q.Returned, @owned Optional<@callee_guaranteed (@guaranteed Change) -> Bool>, @error Error), normal bb7, error bb20 // id: %34
The correct bug fix would have been to add support for doing the transformation in this case (preferable) or make sure we do not bail out in an inconsistent state.
Thank you for the feedback, Joe. It turns out to be non-trivial. Will investigate further. |
6838869
to
f5a743c
Compare
@shajrawi Hi Joe, I took your advice and tried to make the (preferable) solution. Would you help review the updated code, please? Many thanks! |
I am unavailable for the next week or so, Will do so when I get back. it will have to wait, unless @aschwaighofer feels comfortable reviewing that code. |
No problems, Joe. |
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.
Much better! And seems to provide the ideal solution to the crash, actually supporting multi-results, only small changes required.
lib/IRGen/LoadableByAddress.cpp
Outdated
auto newResultType = getNewSILType(genEnv, resultType, Mod); | ||
bool hasFuncSig = containsFunctionSignature(genEnv, Mod, | ||
resultType, newResultType); | ||
return hasFuncSig; |
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.
We should transform the results only if the new SIL type differs in this case. the lowered type may contain a function signature, but, it may remain as-is if it is not loadable and/or not a large type.
In addition, there's no need to duplicate code with the checks further down this function / we can make it smaller: instead of
auto singleResult = loweredTy->getSingleResult();
auto resultStorageType = singleResult.getSILStorageType();
auto newResultStorageType = getNewSILType(genEnv, resultStorageType, Mod);
We should do a similar check on all results type.
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.
I changed the condition to compare resultType
and newResultType
instead of detecting function signature here.
For the second issue, it seems that we cannot simply reuse the code. Because when it comes to single-result case, loweredTy->getAllResultsType()
would return getType() while what we intend to have is getSILStorageType()
. I tried doing a similar check on all results type here, and it unfortunately crashes the compiler on some test code.
lib/IRGen/LoadableByAddress.cpp
Outdated
"Expected a SILFunctionType inside the optional Type"); | ||
} | ||
// Make sure it contains a function type | ||
size_t numFuncTy = llvm::count_if(origSILFunctionType->getResults(), |
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.
Can you please use auto
instead of size_t
?
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.
Done.
//===----------------------------------------------------------------------===// | ||
// SR-8076 | ||
//===----------------------------------------------------------------------===// | ||
public struct sr8076_BigStruct { |
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.
There's no need to define a new data structure here, it is confusing, there's already one called BigStruct
inside the same source file that should do the job.
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.
Reused BigStruct
.
func handle_4(query: Handled) throws -> (Handled.Returned, sr8076_Filter?) | ||
} | ||
|
||
public extension sr8076_QueryHandler { |
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.
Good tests. but, can you please add CHECK
(s) that make sure the resulting IR is correct? right now we are only making sure the compiler doesn't crash, but, we are not looking at the IR to see that it makes sense. Look at some of the CHECK
and CHECK-LABEL
lines inside this very same test file for examples.
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.
Fixed.
When it comes to functions with tuple result types in the LoadableByAddress pass, we do not intend to perform relevant transformation, but somehow some implementation is not right. This patch adds appropriate checks to correct such transformation conditions. Resolves: SR-8076.
Hi Joe, thank you so much for the review. I rebased and updated the code as you suggested. |
@swift-ci Please test |
Build failed |
Looks like some |
@swift-ci please test Linux |
When it comes to functions with tuple result types in the LoadableByAddress pass, the current implementation doesn't intend to perform the transformation, and some inconsistent states cause compiler crashing. This patch adds supports for transformation in such cases.
Resolves SR-8076.
radar rdar://problem/41369680