Skip to content

Commit 1eebdc1

Browse files
Merge pull request #8002 from aschwaighofer/unsafe_guaranteed_spec_devirt
Speculative Devirtualizer: Don't speculate _withUnsafeGuaranteedRef c…
2 parents 69ba7f3 + 76d0f68 commit 1eebdc1

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,17 @@ static bool tryToSpeculateTarget(FullApplySite AI,
329329
if (CMI->isVolatile())
330330
return false;
331331

332+
// Don't devirtualize withUnsafeGuaranteed 'self' as this would prevent
333+
// retain/release removal.
334+
// unmanged._withUnsafeGuaranteedRef { $0.method() }
335+
if (auto *TupleExtract = dyn_cast<TupleExtractInst>(CMI->getOperand()))
336+
if (auto *UnsafeGuaranteedSelf =
337+
dyn_cast<BuiltinInst>(TupleExtract->getOperand()))
338+
if (UnsafeGuaranteedSelf->getBuiltinKind() ==
339+
BuiltinValueKind::UnsafeGuaranteed &&
340+
TupleExtract->getFieldNo() == 0)
341+
return false;
342+
332343
// Strip any upcasts off of our 'self' value, potentially leaving us
333344
// with a value whose type is closer (in the class hierarchy) to the
334345
// actual dynamic type.

test/SILOptimizer/devirt_speculative.sil

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
sil_stage canonical
44

5+
import Builtin
6+
57
@objc class MyNSObject {}
68
private class Base : MyNSObject {
79
override init()
@@ -104,3 +106,21 @@ bb0(%0: $Base2):
104106
// CHECK: checked_cast_br [exact] %0 : $Base2 to $Sub2, bb{{.*}}, bb[[GENCALL:[0-9]+]]
105107
// CHECK: bb[[GENCALL]]{{.*}}:
106108
// CHECK: apply [[METH]]
109+
110+
// Don't devirtualize 'unsafeGuaranteed' self calls.
111+
// CHECK-LABEL: sil @test_unsafeGuaranteed
112+
// CHECK-NOT: check_cast_br
113+
// CHECK: return
114+
sil @test_unsafeGuaranteed : $@convention(thin) (@guaranteed Base2) -> () {
115+
bb0(%0: $Base2):
116+
strong_retain %0 : $Base2
117+
%4 = builtin "unsafeGuaranteed"<Base2>(%0 : $Base2) : $(Base2, Builtin.Int8)
118+
%5 = tuple_extract %4 : $(Base2, Builtin.Int8), 0
119+
%6 = tuple_extract %4 : $(Base2, Builtin.Int8), 1
120+
%1 = class_method %0 : $Base2, #Base2.foo!1 : (Base2) -> () -> (), $@convention(method) (@guaranteed Base2) -> ()
121+
%2 = apply %1(%5) : $@convention(method) (@guaranteed Base2) -> ()
122+
strong_release %5 : $Base2
123+
%16 = builtin "unsafeGuaranteedEnd"(%6 : $Builtin.Int8) : $()
124+
%3 = tuple()
125+
return %3 : $()
126+
}

0 commit comments

Comments
 (0)