Skip to content

Commit 160d01a

Browse files
committed
Generic Specializer: Use getResilienceExpansion() throughout ReabstractionInfo
It must be consistent, otherwise the specialized function types may not match for calls in functions with different resilience expansions. Fixes an assertion crash in the generic specializer. rdar://problem/57844964
1 parent d93f96e commit 160d01a

File tree

3 files changed

+42
-14
lines changed

3 files changed

+42
-14
lines changed

include/swift/SILOptimizer/Utils/Generics.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,14 @@ void trySpecializeApplyOfGeneric(
5353
/// Specifically, it contains information which formal parameters and returns
5454
/// are changed from indirect values to direct values.
5555
class ReabstractionInfo {
56-
/// A 1-bit means that this parameter/return value is converted from indirect
57-
/// to direct.
56+
/// A 1-bit means that this argument (= either indirect return value or
57+
/// parameter) is converted from indirect to direct.
5858
SmallBitVector Conversions;
5959

60+
/// For each bit set in Conversions, there is a bit set in TrivialArgs if the
61+
/// argument has a trivial type.
62+
SmallBitVector TrivialArgs;
63+
6064
/// If set, indirect to direct conversions should be performed by the generic
6165
/// specializer.
6266
bool ConvertIndirectToDirect;
@@ -121,6 +125,10 @@ class ReabstractionInfo {
121125

122126
// Is the generated specialization going to be serialized?
123127
IsSerialized_t Serialized;
128+
129+
unsigned param2ArgIndex(unsigned ParamIdx) const {
130+
return ParamIdx + NumFormalIndirectResults;
131+
}
124132

125133
// Create a new substituted type with the updated signature.
126134
CanSILFunctionType createSubstitutedType(SILFunction *OrigF,
@@ -171,8 +179,7 @@ class ReabstractionInfo {
171179
/// Returns true if the \p ParamIdx'th (non-result) formal parameter is
172180
/// converted from indirect to direct.
173181
bool isParamConverted(unsigned ParamIdx) const {
174-
return ConvertIndirectToDirect &&
175-
Conversions.test(ParamIdx + NumFormalIndirectResults);
182+
return ConvertIndirectToDirect && isArgConverted(param2ArgIndex(ParamIdx));
176183
}
177184

178185
/// Returns true if the \p ResultIdx'th formal result is converted from

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -670,8 +670,10 @@ void ReabstractionInfo::createSubstitutedAndSpecializedTypes() {
670670
// Check which parameters and results can be converted from
671671
// indirect to direct ones.
672672
NumFormalIndirectResults = SubstitutedType->getNumIndirectFormalResults();
673-
Conversions.resize(NumFormalIndirectResults +
674-
SubstitutedType->getParameters().size());
673+
unsigned NumArgs = NumFormalIndirectResults +
674+
SubstitutedType->getParameters().size();
675+
Conversions.resize(NumArgs);
676+
TrivialArgs.resize(NumArgs);
675677

676678
CanGenericSignature CanSig;
677679
if (SpecializedGenericSig)
@@ -696,6 +698,8 @@ void ReabstractionInfo::createSubstitutedAndSpecializedTypes() {
696698
if (TL.isLoadable() && !RI.getReturnValueType(M, SubstitutedType)->isVoid() &&
697699
shouldExpand(M, ResultTy)) {
698700
Conversions.set(IdxForResult);
701+
if (TL.isTrivial())
702+
TrivialArgs.set(IdxForResult);
699703
break;
700704
}
701705
++IdxForResult;
@@ -721,6 +725,8 @@ void ReabstractionInfo::createSubstitutedAndSpecializedTypes() {
721725
case ParameterConvention::Indirect_In:
722726
case ParameterConvention::Indirect_In_Guaranteed:
723727
Conversions.set(IdxToInsert);
728+
if (TL.isTrivial())
729+
TrivialArgs.set(IdxToInsert);
724730
break;
725731
case ParameterConvention::Indirect_In_Constant:
726732
case ParameterConvention::Indirect_Inout:
@@ -796,14 +802,12 @@ createSpecializedType(CanSILFunctionType SubstFTy, SILModule &M) const {
796802
unsigned IndirectResultIdx = 0;
797803
for (SILResultInfo RI : SubstFTy->getResults()) {
798804
if (RI.isFormalIndirect()) {
805+
bool isTrivial = TrivialArgs.test(IndirectResultIdx);
799806
if (isFormalResultConverted(IndirectResultIdx++)) {
800807
// Convert the indirect result to a direct result.
801-
SILType SILResTy =
802-
SILType::getPrimitiveObjectType(RI.getReturnValueType(M, SubstFTy));
803-
804808
// Indirect results are passed as owned, so we also need to pass the
805809
// direct result as owned (except it's a trivial type).
806-
auto C = (SILResTy.isTrivial(*Callee)
810+
auto C = (isTrivial
807811
? ResultConvention::Unowned
808812
: ResultConvention::Owned);
809813
SpecializedResults.push_back(SILResultInfo(RI.getReturnValueType(M, SubstFTy), C));
@@ -815,21 +819,19 @@ createSpecializedType(CanSILFunctionType SubstFTy, SILModule &M) const {
815819
}
816820
unsigned ParamIdx = 0;
817821
for (SILParameterInfo PI : SubstFTy->getParameters()) {
822+
bool isTrivial = TrivialArgs.test(param2ArgIndex(ParamIdx));
818823
if (!isParamConverted(ParamIdx++)) {
819824
// No conversion: re-use the original, substituted parameter info.
820825
SpecializedParams.push_back(PI);
821826
continue;
822827
}
823828

824829
// Convert the indirect parameter to a direct parameter.
825-
SILType SILParamTy =
826-
SILType::getPrimitiveObjectType(PI.getArgumentType(M, SubstFTy));
827-
828830
// Indirect parameters are passed as owned/guaranteed, so we also
829831
// need to pass the direct/guaranteed parameter as
830832
// owned/guaranteed (except it's a trivial type).
831833
auto C = ParameterConvention::Direct_Unowned;
832-
if (!SILParamTy.isTrivial(*Callee)) {
834+
if (!isTrivial) {
833835
if (PI.isGuaranteed()) {
834836
C = ParameterConvention::Direct_Guaranteed;
835837
} else {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-frontend -parse-as-library -O -module-name=test %s -enable-library-evolution -emit-sil | %FileCheck %s
2+
3+
public enum En {
4+
case A
5+
case B
6+
}
7+
8+
@inlinable
9+
@inline(never)
10+
func genfunc<T>(_ t: T) -> T {
11+
return t
12+
}
13+
14+
// CHECK-LABEL: sil @$s4test11callGenFuncyyF : $@convention(thin) () -> () {
15+
// CHECK: = function_ref @$s4test7genfuncyxxlFAA2EnO_Tg5 : $@convention(thin) (En) -> @out En
16+
// CHECK: } // end sil function '$s4test11callGenFuncyyF'
17+
public func callGenFunc() {
18+
_ = genfunc(En.A)
19+
}

0 commit comments

Comments
 (0)