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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ private extension UnaryInstruction {
operand.set(to: replacement, context)
}

if let ccb = self as? CheckedCastBranchInst {
// Make sure that updating the formal type with the operand type is
// legal.
if operand.value.type.isLegalFormalType {
ccb.updateSourceFormalTypeFromOperandLoweredType()
}
}
if canEraseInst {
context.erase(instructionIncludingDebugUses: inst)
}
Expand Down
4 changes: 4 additions & 0 deletions SwiftCompilerSources/Sources/SIL/Instruction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1696,6 +1696,10 @@ final public class CheckedCastBranchInst : TermInst, UnaryInstruction {
public var source: Value { operand.value }
public var successBlock: BasicBlock { bridged.CheckedCastBranch_getSuccessBlock().block }
public var failureBlock: BasicBlock { bridged.CheckedCastBranch_getFailureBlock().block }

public func updateSourceFormalTypeFromOperandLoweredType() {
bridged.CheckedCastBranch_updateSourceFormalTypeFromOperandLoweredType()
}
}

final public class CheckedCastAddrBranchInst : TermInst {
Expand Down
2 changes: 2 additions & 0 deletions SwiftCompilerSources/Sources/SIL/Type.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ public struct Type : CustomStringConvertible, NoReflectionChildren {
public var isBuiltinVector: Bool { bridged.isBuiltinVector() }
public var builtinVectorElementType: Type { bridged.getBuiltinVectorElementType().type }

public var isLegalFormalType: Bool { bridged.isLegalFormalType() }

public func isBuiltinInteger(withFixedWidth width: Int) -> Bool {
bridged.isBuiltinFixedWidthInteger(width)
}
Expand Down
2 changes: 2 additions & 0 deletions include/swift/SIL/SILBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ struct BridgedType {
BRIDGED_INLINE bool isBuiltinInteger() const;
BRIDGED_INLINE bool isBuiltinFloat() const;
BRIDGED_INLINE bool isBuiltinVector() const;
BRIDGED_INLINE bool isLegalFormalType() const;
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedType getBuiltinVectorElementType() const;
BRIDGED_INLINE bool isBuiltinFixedWidthInteger(SwiftInt width) const;
BRIDGED_INLINE bool isExactSuperclassOf(BridgedType t) const;
Expand Down Expand Up @@ -810,6 +811,7 @@ struct BridgedInstruction {
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedBasicBlock CheckedCastBranch_getFailureBlock() const;
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedBasicBlock CheckedCastAddrBranch_getSuccessBlock() const;
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedBasicBlock CheckedCastAddrBranch_getFailureBlock() const;
BRIDGED_INLINE void CheckedCastBranch_updateSourceFormalTypeFromOperandLoweredType() const;
BRIDGED_INLINE CastConsumptionKind CheckedCastAddrBranch_getConsumptionKind() const;
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedSubstitutionMap ApplySite_getSubstitutionMap() const;
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedCanType ApplySite_getSubstitutedCalleeType() const;
Expand Down
8 changes: 8 additions & 0 deletions include/swift/SIL/SILBridgingImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,10 @@ bool BridgedType::isBuiltinVector() const {
return unbridged().isBuiltinVector();
}

bool BridgedType::isLegalFormalType() const {
return unbridged().getASTType()->isLegalFormalType();
}

BridgedType BridgedType::getBuiltinVectorElementType() const {
return unbridged().getBuiltinVectorElementType();
}
Expand Down Expand Up @@ -1504,6 +1508,10 @@ void BridgedInstruction::LoadInst_setOwnership(SwiftInt ownership) const {
getAs<swift::LoadInst>()->setOwnershipQualifier((swift::LoadOwnershipQualifier)ownership);
}

void BridgedInstruction::CheckedCastBranch_updateSourceFormalTypeFromOperandLoweredType() const {
getAs<swift::CheckedCastBranchInst>()->updateSourceFormalTypeFromOperandLoweredType();
}

BridgedBasicBlock BridgedInstruction::CheckedCastBranch_getSuccessBlock() const {
return {getAs<swift::CheckedCastBranchInst>()->getSuccessBB()};
}
Expand Down
4 changes: 4 additions & 0 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

SrcFormalTy = getSourceLoweredType().getASTType();
}

SILType getTargetLoweredType() const { return DestLoweredTy; }
CanType getTargetFormalType() const { return DestFormalTy; }
};
Expand Down
2 changes: 1 addition & 1 deletion test/DebugInfo/simplify_checked_cast_br.sil
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class X : B {}

// CHECK-LABEL: sil [ossa] @test_ossa :
// CHECK: %0 = alloc_ref
// CHECK-NEXT: checked_cast_br AnyObject in %0 : $X
// CHECK-NEXT: checked_cast_br X in %0 : $X
// CHECK: bb2([[A:%.*]] : @owned $X):
// CHECK-NEXT: [[U:%.*]] = upcast [[A]] : $X to $B, loc "takethis":1:1
// CHECK-NEXT: [[E:%.*]] = init_existential_ref [[U]] {{.+}}, loc "takethis":1:1
Expand Down
2 changes: 1 addition & 1 deletion test/SILOptimizer/devirt_covariant_return.swift
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ public class D2: D1 {
// that D2.foo() is inlined thanks to this.
// CHECK-LABEL: sil hidden [noinline] @$s23devirt_covariant_return7driver2ys5Int32VAA2D2CF
// CHECK-NOT: class_method
// CHECK: checked_cast_br [exact] D1 in
// CHECK: checked_cast_br [exact] D2 in
// CHECK: bb2
// CHECK: global_addr
// CHECK: load
Expand Down
6 changes: 3 additions & 3 deletions test/SILOptimizer/simplify_checked_cast_br.sil
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class X : B {}

// CHECK-LABEL: sil @test_non_ossa :
// CHECK: %0 = alloc_ref
// CHECK: checked_cast_br AnyObject in %0 : $X
// CHECK: checked_cast_br X in %0 : $X
// CHECK: } // end sil function 'test_non_ossa'
sil @test_non_ossa : $@convention(thin) () -> AnyObject {
bb0:
Expand All @@ -31,7 +31,7 @@ bb2:

// CHECK-LABEL: sil [ossa] @test_ossa :
// CHECK: %0 = alloc_ref
// CHECK-O-NEXT: checked_cast_br AnyObject in %0 : $X
// CHECK-O-NEXT: checked_cast_br X in %0 : $X
// CHECK-ONONE: checked_cast_br AnyObject in %2 : $AnyObject
// CHECK-O: bb2([[A:%.*]] : @owned $X):
// CHECK-O-NEXT: [[U:%.*]] = upcast [[A]] : $X to $B
Expand Down Expand Up @@ -75,7 +75,7 @@ bb2(%7 : @owned $B):

// CHECK-LABEL: sil [ossa] @test_borrow :
// CHECK: %1 = begin_borrow
// CHECK-NEXT: checked_cast_br any P in %1 : $X
// CHECK-NEXT: checked_cast_br X in %1 : $X
// CHECK: bb2([[A:%.*]] : @guaranteed $X):
// CHECK-NEXT: [[U:%.*]] = upcast [[A]] : $X to $B
// CHECK-NEXT: [[E:%.*]] = init_existential_ref [[U]] : $B
Expand Down