Skip to content

Commit ec2b108

Browse files
committed
[AddressLowering] Handle unchecked to loadable.
When casting via unchecked_bitwise_cast, if the destination type is loadable, don't mark the value it produces rewritten--that value is not one that AddressLowering is tracking. Instead, replace its copy_value uses with load [copy] uses of the address the rewritten instruction produces.
1 parent 0aca521 commit ec2b108

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

lib/SILOptimizer/Mandatory/AddressLowering.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2776,7 +2776,20 @@ class UseRewriter : SILInstructionVisitor<UseRewriter> {
27762776
uncheckedCastInst->getLoc(), srcAddr,
27772777
uncheckedCastInst->getType().getAddressType());
27782778

2779-
markRewritten(uncheckedCastInst, destAddr);
2779+
if (uncheckedCastInst->getType().isAddressOnly(*pass.function)) {
2780+
markRewritten(uncheckedCastInst, destAddr);
2781+
return;
2782+
}
2783+
2784+
// For loadable cast destination type, replace copies with load copies.
2785+
if (Operand *use = uncheckedCastInst->getSingleUse()) {
2786+
if (auto *cvi = dyn_cast<CopyValueInst>(use->getUser())) {
2787+
auto *load = builder.createLoad(cvi->getLoc(), destAddr,
2788+
LoadOwnershipQualifier::Copy);
2789+
cvi->replaceAllUsesWith(load);
2790+
pass.deleter.forceDelete(cvi);
2791+
}
2792+
}
27802793
}
27812794

27822795
void visitUnconditionalCheckedCastInst(

test/SILOptimizer/opaque_values_Onone_stdlib.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,23 @@ func getRawPointer<T>(to value: T) -> Builtin.RawPointer {
5050
func getUnprotectedRawPointer<T>(to value: T) -> Builtin.RawPointer {
5151
return Builtin.unprotectedAddressOfBorrow(value)
5252
}
53+
54+
// CHECK-LABEL: sil hidden @getBridgeObject : {{.*}} {
55+
// CHECK: [[OBJECT_ADDR:%[^,]+]] = unchecked_addr_cast {{%[^,]+}} : $*T to $*Builtin.BridgeObject
56+
// CHECK: [[OBJECT:%[^,]+]] = load [[OBJECT_ADDR]]
57+
// CHECK: return [[OBJECT]]
58+
// CHECK-LABEL: } // end sil function 'getBridgeObject'
59+
@_silgen_name("getBridgeObject")
60+
func toObject<T>(_ object: inout T) -> Builtin.BridgeObject {
61+
Builtin.reinterpretCast(object)
62+
}
63+
64+
// CHECK-LABEL: sil hidden @getAnotherType : {{.*}} {
65+
// CHECK: {{bb[0-9]+}}([[RETADDR:%[^,]+]] : $*U, {{%[^,]+}} : $*T, {{%[^,]+}} : $@thick U.Type):
66+
// CHECK: [[OTHER_TY_ADDR:%[^,]+]] = unchecked_addr_cast {{%[^,]+}} : $*T to $*U
67+
// CHECK: copy_addr [[OTHER_TY_ADDR]] to [init] [[RETADDR]] : $*U
68+
// CHECK-LABEL: } // end sil function 'getAnotherType'
69+
@_silgen_name("getAnotherType")
70+
func getAnotherType<T, U>(_ object: inout T, to ty: U.Type) -> U {
71+
Builtin.reinterpretCast(object)
72+
}

0 commit comments

Comments
 (0)