Skip to content

SIL: Update formal source type in SimplifyRefCasts when possible #78996

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

Conversation

aschwaighofer
Copy link
Contributor

We use the formal source type do decide whether a checked_cast_br is known to succeed/fail. If we don't update it we loose that optimization

That is:

  checked_cast_br AnyObject in %2 : X to X, bb1, bb2

Will not be simplified even though the operand and the destintation type matches.

@aschwaighofer
Copy link
Contributor Author

@swift-ci test

// formal source type lowered equaled the operand SIL type before
// transformation).
let formalSrcType = ccb.formalSrcType
if formalSrcType.loweredType(in: parentFunction, maximallyAbstracted: false) == oldOperandType {
Copy link
Contributor Author

@aschwaighofer aschwaighofer Jan 29, 2025

Choose a reason for hiding this comment

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

Why this weird check?

#67583

It seems we can't always use the operand`s lowered SIL type (SIL type lowering has lost some information?! unfortunate ...) but need to carry the formal type.

So this check here checks that the when we lower the formal type to a SIL type we get the same type ie. we are not one of the cases where during the process of SIL lowering information was lost.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Except, that as I write this I realize the check should be formalSrcType == oldOperandType.astType

@aschwaighofer aschwaighofer force-pushed the checked_cast_br_nightmares branch from da2730a to 44f03b9 Compare January 29, 2025 00:58
@aschwaighofer
Copy link
Contributor Author

@swift-ci test

@@ -86,6 +88,15 @@ private extension UnaryInstruction {
operand.set(to: replacement, context)
}

if let ccb = self as? CheckedCastBranchInst {
// Make sure that loosing the formal source type is harmless (i.e the
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand this comment. I think what you want to check is the following:
if the lowered source operand type is the formal type before the transformation we can assume that the type of the new operand is also a formal type.

Is this assumption always true?
Wouldn't it be better to just check if the new operand type isLegalFormalType()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Forgot to update the comment after updating the code. Have you seen my comment on this PR above?

Yes you are right: The comment should say: if the lowered source operand type is the formal type before the transformation we can assume that no information was lost during type lowering.

Does isLegalFormalType check this condition?

It is not clear to me that this is why checked _cast_addr_br needs the formal source type:
#67583

Copy link
Contributor

Choose a reason for hiding this comment

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

It is not clear to me that this is why checked _cast_addr_br needs the formal source type:

It's used in IRGen (visitCheckedCastAddrBranchInst). I assume the runtime type/cast machinery needs formal types rather than lowered types.

Does isLegalFormalType check this condition?

I think if the new SILType is a formal type (which isLegalFormalType should check) it's fine to use it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, let's use that.

@@ -11032,6 +11032,10 @@ class CheckedCastBranchInst final
SILType getSourceLoweredType() const { return getOperand()->getType(); }
CanType getSourceFormalType() const { return SrcFormalTy; }

void updateSourceFormalTypeFromOperandLoweredType() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not setSourceFormalType(CanType newFormalType)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add the ability to set any unrelated formal type?

Copy link
Contributor

Choose a reason for hiding this comment

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

good point

We use the formal source type do decide whether a checked_cast_br is
known to succeed/fail. If we don't update it we loose that optimization

That is:

```
  checked_cast_br AnyObject in %2 : X to X, bb1, bb2
```

Will not be simplified even though the operand and the destintation type
matches.
@aschwaighofer aschwaighofer force-pushed the checked_cast_br_nightmares branch from 44f03b9 to 0fe3cf0 Compare January 29, 2025 17:33
Copy link
Contributor

@eeckstein eeckstein left a comment

Choose a reason for hiding this comment

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

lgtm

@aschwaighofer
Copy link
Contributor Author

@swift-ci test

@aschwaighofer aschwaighofer merged commit c95c452 into swiftlang:main Feb 2, 2025
5 checks passed
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.

2 participants