Skip to content

Commit 66ccfd7

Browse files
committed
Inliner: fix condition to prevent inlining of functions with dynamic-self.
Now the condition matches exactly what's checked in asserts in SILBuilder. fixes an assert in the PerformanceInliner https://bugs.swift.org/browse/SR-11817 rdar://problem/57369847
1 parent d2e1f09 commit 66ccfd7

File tree

3 files changed

+31
-5
lines changed

3 files changed

+31
-5
lines changed

lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -735,9 +735,9 @@ SILFunction *swift::getEligibleFunction(FullApplySite AI,
735735
// Check if passed Self is the same as the Self of the caller.
736736
// In this case, it is safe to inline because both functions
737737
// use the same Self.
738-
if (AI.hasSelfArgument() && Caller->hasSelfParam()) {
738+
if (AI.hasSelfArgument() && Caller->hasSelfMetadataParam()) {
739739
auto CalleeSelf = stripCasts(AI.getSelfArgument());
740-
auto CallerSelf = Caller->getSelfArgument();
740+
auto CallerSelf = Caller->getSelfMetadataArgument();
741741
if (CalleeSelf != SILValue(CallerSelf))
742742
return nullptr;
743743
} else

test/SILOptimizer/performance_inliner.sil

+26
Original file line numberDiff line numberDiff line change
@@ -968,3 +968,29 @@ bb2(%7 : $Error):
968968
sil_vtable C {
969969
#C.callThrowing!1: @callThrowing
970970
}
971+
972+
// Test that the inliner doesn't crash if a dynamic-self callee is called from a
973+
// non-dynamic-self caller. Currently we just prevent inlining in this case.
974+
// We could handle this at some time, but we must not crash.
975+
976+
class X { }
977+
protocol PX : X { }
978+
979+
sil @no_self_metadata : $@convention(method) <Self where Self : PX> (@thick Self.Type) -> () {
980+
bb0(%1 : $@thick Self.Type):
981+
%4 = upcast %1 : $@thick Self.Type to $@thick X.Type
982+
%5 = function_ref @has_self_metadata : $@convention(method) (@thick X.Type) -> @owned X
983+
%6 = apply %5(%4) : $@convention(method) (@thick X.Type) -> @owned X
984+
strong_release %6 : $X
985+
%8 = tuple ()
986+
return %8 : $()
987+
}
988+
989+
sil [always_inline] @has_self_metadata : $@convention(method) (@thick X.Type) -> @owned X {
990+
bb0(%1 : $@thick X.Type):
991+
%3 = unchecked_trivial_bit_cast %1 : $@thick X.Type to $@thick @dynamic_self X.Type
992+
%27 = upcast %3 : $@thick @dynamic_self X.Type to $@thick X.Type
993+
%30 = alloc_ref_dynamic %27 : $@thick X.Type, $X
994+
return %30 : $X
995+
}
996+

test/SILOptimizer/specialize_dynamic_self.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
// RUN: %target-swift-frontend -module-name specialize_dynamic_self -Xllvm -sil-inline-generics -emit-sil -O -primary-file %s | %FileCheck %s
2+
// RUN: %target-swift-frontend -module-name specialize_dynamic_self -Xllvm -sil-disable-pass=FunctionSignatureOpts -emit-sil -O -primary-file %s | %FileCheck %s
33

44
protocol P {}
55

@@ -10,12 +10,12 @@ extension P {
1010
}
1111

1212
class C<T> : P {
13-
// CHECK-LABEL: sil shared [always_inline] @$s23specialize_dynamic_self1CC11returnsSelfACyxGXDyFSi_Tg5 : $@convention(method) (@guaranteed C<Int>) -> @owned C<Int>
13+
// CHECK-LABEL: sil shared [noinline] @$s23specialize_dynamic_self1CC11returnsSelfACyxGXDyFSi_Tg5 : $@convention(method) (@guaranteed C<Int>) -> @owned C<Int>
1414
// CHECK: [[RESULT:%.*]] = alloc_stack $C<Int>
1515
// CHECK: [[FN:%.*]] = function_ref @$s23specialize_dynamic_self1PPAAE7method1yyF : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
1616
// CHECK: apply [[FN]]<@dynamic_self C<Int>>([[RESULT]]) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> ()
1717
// CHECK: return %0 : $C<Int>
18-
@inline(__always)
18+
@inline(never)
1919
final func returnsSelf() -> Self {
2020
method2()
2121
return self

0 commit comments

Comments
 (0)