Skip to content

Commit 9647c2f

Browse files
authored
Merge pull request #24022 from gottesmm/pr-a1ae58834b206c823e8bffaad277ac8bf72ae2f3
[cast-opt] Create an ownership version of bridged_cast_folding.sil an…
2 parents 6319820 + 1983368 commit 9647c2f

File tree

3 files changed

+120
-9
lines changed

3 files changed

+120
-9
lines changed

lib/SILOptimizer/Utils/CastOptimizer.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -514,13 +514,18 @@ static SILValue computeFinalCastedValue(SILBuilderWithScope &builder,
514514
auto *failureBB = dynamicCast.getFailureBlock();
515515
{
516516
SILBuilderWithScope innerBuilder(&*failureBB->begin(), builder);
517-
innerBuilder.emitDestroyValueOperation(loc, newAI);
517+
auto valueToDestroy = ([&]() -> SILValue {
518+
if (!innerBuilder.hasOwnership())
519+
return newAI;
520+
return failureBB->createPhiArgument(newAI->getType(),
521+
ValueOwnershipKind::Owned);
522+
}());
523+
innerBuilder.emitDestroyValueOperation(loc, valueToDestroy);
518524
}
519525

520526
auto *condBrSuccessBB =
521527
newAI->getFunction()->createBasicBlockAfter(newAI->getParent());
522-
condBrSuccessBB->createPhiArgument(destTy, ValueOwnershipKind::Owned,
523-
nullptr);
528+
condBrSuccessBB->createPhiArgument(destTy, ValueOwnershipKind::Owned);
524529
builder.createCheckedCastBranch(loc, /* isExact*/ false, newAI, destTy,
525530
condBrSuccessBB, failureBB);
526531
builder.setInsertionPoint(condBrSuccessBB, condBrSuccessBB->begin());
@@ -709,10 +714,13 @@ CastOptimizer::optimizeBridgedSwiftToObjCCast(SILDynamicCastInst dynamicCast) {
709714
if (!Dest)
710715
return NewAI;
711716

712-
// If it is addr cast then store the result.
717+
// If it is addr cast then store the result into the dest.
718+
//
719+
// NOTE: We assume that dest was uninitialized when passed to us.
713720
SILValue castedValue = computeFinalCastedValue(Builder, dynamicCast, NewAI);
714-
SILInstruction *NewI = Builder.createStore(
715-
Loc, castedValue, Dest, StoreOwnershipQualifier::Unqualified);
721+
auto qual = Builder.hasOwnership() ? StoreOwnershipQualifier::Init
722+
: StoreOwnershipQualifier::Unqualified;
723+
SILInstruction *NewI = Builder.createStore(Loc, castedValue, Dest, qual);
716724
if (isConditional && NewI->getParent() != NewAI->getParent()) {
717725
Builder.createBranch(Loc, SuccessBB);
718726
}

test/SILOptimizer/bridged_casts_folding.sil

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ bb1:
4141

4242
bb2:
4343
br bb3(%1 : $NSObjectSubclass)
44-
44+
4545
bb3(%8 : @owned $NSObjectSubclass):
4646
dealloc_stack %2 : $*NSObjectSubclass
4747
return %8 : $NSObjectSubclass
@@ -66,7 +66,7 @@ bb1:
6666
bb2:
6767
destroy_addr %0 : $*AnyHashable
6868
br bb3(%1 : $NSObjectSubclass)
69-
69+
7070
bb3(%8 : @owned $NSObjectSubclass):
7171
dealloc_stack %2 : $*NSObjectSubclass
7272
return %8 : $NSObjectSubclass
@@ -94,7 +94,7 @@ bb1:
9494

9595
bb2:
9696
br bb3(%1 : $NSObjectSubclass)
97-
97+
9898
bb3(%8 : @owned $NSObjectSubclass):
9999
dealloc_stack %2 : $*NSObjectSubclass
100100
return %8 : $NSObjectSubclass
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// RUN: %target-swift-frontend -enable-ownership-stripping-after-serialization -module-name bridged_casts_folding -O -emit-sil %s | %FileCheck %s
2+
3+
// REQUIRES: objc_interop
4+
5+
sil_stage raw
6+
7+
import Swift
8+
import Foundation
9+
10+
class NSObjectSubclass : NSObject {}
11+
sil_vtable NSObjectSubclass {}
12+
13+
// CHECK-LABEL: sil @anyhashable_cast_unconditional :
14+
// CHECK: [[BRIDGED:%.*]] = apply {{.*}}(%0)
15+
// CHECK-NEXT: destroy_addr %0
16+
// CHECK-NEXT: [[CAST:%.*]] = unconditional_checked_cast [[BRIDGED]] : $NSObject to $NSObjectSubclass
17+
// CHECK-NEXT: return [[CAST]]
18+
// CHECK: } // end sil function 'anyhashable_cast_unconditional'
19+
sil [ossa] @anyhashable_cast_unconditional : $@convention(thin) (@in AnyHashable) -> @owned NSObjectSubclass {
20+
entry(%0 : $*AnyHashable):
21+
%1 = alloc_stack $NSObjectSubclass
22+
unconditional_checked_cast_addr AnyHashable in %0 : $*AnyHashable
23+
to NSObjectSubclass in %1 : $*NSObjectSubclass
24+
%3 = load [take] %1 : $*NSObjectSubclass
25+
dealloc_stack %1 : $*NSObjectSubclass
26+
return %3 : $NSObjectSubclass
27+
}
28+
29+
// CHECK-LABEL: sil @anyhashable_cast_take_always
30+
// CHECK: [[BRIDGED:%.*]] = apply {{.*}}(%0)
31+
// CHECK-NEXT: destroy_addr %0
32+
// CHECK-NEXT: checked_cast_br [[BRIDGED]] : $NSObject to $NSObjectSubclass, [[YES:bb[0-9]+]], [[NO:bb[0-9]+]]
33+
sil [ossa] @anyhashable_cast_take_always : $@convention(thin) (@in AnyHashable, @owned NSObjectSubclass) -> @owned NSObjectSubclass {
34+
entry(%0 : $*AnyHashable, %1 : @owned $NSObjectSubclass):
35+
%2 = alloc_stack $NSObjectSubclass
36+
checked_cast_addr_br take_always AnyHashable in %0 : $*AnyHashable
37+
to NSObjectSubclass in %2 : $*NSObjectSubclass, bb1, bb2
38+
39+
bb1:
40+
%4 = load [take] %2 : $*NSObjectSubclass
41+
destroy_value %1 : $NSObjectSubclass
42+
br bb3(%4 : $NSObjectSubclass)
43+
44+
bb2:
45+
br bb3(%1 : $NSObjectSubclass)
46+
47+
bb3(%8 : @owned $NSObjectSubclass):
48+
dealloc_stack %2 : $*NSObjectSubclass
49+
return %8 : $NSObjectSubclass
50+
}
51+
52+
// CHECK-LABEL: sil @anyhashable_cast_take_on_success
53+
// CHECK: [[BRIDGED:%.*]] = apply {{.*}}(%0)
54+
// CHECK-NEXT: checked_cast_br [[BRIDGED]] : $NSObject to $NSObjectSubclass, [[YES:bb[0-9]+]], [[NO:bb[0-9]+]]
55+
// CHECK: [[YES]]{{.*}}:
56+
// CHECK-NEXT: destroy_addr %0
57+
sil [ossa] @anyhashable_cast_take_on_success : $@convention(thin) (@in AnyHashable, @owned NSObjectSubclass) -> @owned NSObjectSubclass {
58+
entry(%0 : $*AnyHashable, %1 : @owned $NSObjectSubclass):
59+
%2 = alloc_stack $NSObjectSubclass
60+
checked_cast_addr_br take_on_success AnyHashable in %0 : $*AnyHashable
61+
to NSObjectSubclass in %2 : $*NSObjectSubclass, bb1, bb2
62+
63+
bb1:
64+
%4 = load [take] %2 : $*NSObjectSubclass
65+
destroy_value %1 : $NSObjectSubclass
66+
br bb3(%4 : $NSObjectSubclass)
67+
68+
bb2:
69+
destroy_addr %0 : $*AnyHashable
70+
br bb3(%1 : $NSObjectSubclass)
71+
72+
bb3(%8 : @owned $NSObjectSubclass):
73+
dealloc_stack %2 : $*NSObjectSubclass
74+
return %8 : $NSObjectSubclass
75+
}
76+
77+
// CHECK-LABEL: sil @anyhashable_cast_copy_on_success
78+
// CHECK-NOT: copy_addr
79+
// CHECK: [[BRIDGED:%.*]] = apply {{.*}}(%0)
80+
// CHECK-NOT: destroy_addr
81+
// CHECK-NEXT: checked_cast_br [[BRIDGED]] : $NSObject to $NSObjectSubclass, [[YES:bb[0-9]+]], [[NO:bb[0-9]+]]
82+
// CHECK: [[YES]]{{.*}}:
83+
// CHECK-NOT: dealloc_stack
84+
// CHECK: [[NO]]{{.*}}:
85+
// CHECK-NOT: dealloc_stack
86+
sil [ossa] @anyhashable_cast_copy_on_success : $@convention(thin) (@in_guaranteed AnyHashable, @owned NSObjectSubclass) -> @owned NSObjectSubclass {
87+
entry(%0 : $*AnyHashable, %1 : @owned $NSObjectSubclass):
88+
%2 = alloc_stack $NSObjectSubclass
89+
checked_cast_addr_br copy_on_success AnyHashable in %0 : $*AnyHashable
90+
to NSObjectSubclass in %2 : $*NSObjectSubclass, bb1, bb2
91+
92+
bb1:
93+
%4 = load [take] %2 : $*NSObjectSubclass
94+
destroy_value %1 : $NSObjectSubclass
95+
br bb3(%4 : $NSObjectSubclass)
96+
97+
bb2:
98+
br bb3(%1 : $NSObjectSubclass)
99+
100+
bb3(%8 : @owned $NSObjectSubclass):
101+
dealloc_stack %2 : $*NSObjectSubclass
102+
return %8 : $NSObjectSubclass
103+
}

0 commit comments

Comments
 (0)