Skip to content

Commit 7233800

Browse files
authored
Merge pull request #12162 from swiftix/swift-4.0-branch-fixes1
[sil-combine] Fix a bug in the convert_function peephole
2 parents 58e8c21 + 99f183b commit 7233800

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,12 @@ SILCombiner::optimizeApplyOfConvertFunctionInst(FullApplySite AI,
417417
if (SubstCalleeTy->hasArchetype() || ConvertCalleeTy->hasArchetype())
418418
return nullptr;
419419

420+
// Bail if the result type of the converted callee is different from the callee's
421+
// result type of the apply instruction.
422+
if (SubstCalleeTy->getAllResultsType() != ConvertCalleeTy->getAllResultsType()) {
423+
return nullptr;
424+
}
425+
420426
// Ok, we can now perform our transformation. Grab AI's operands and the
421427
// relevant types from the ConvertFunction function type and AI.
422428
Builder.setCurrentDebugScope(AI.getDebugScope());
@@ -461,9 +467,13 @@ SILCombiner::optimizeApplyOfConvertFunctionInst(FullApplySite AI,
461467
NAI = Builder.createTryApply(AI.getLoc(), FRI,
462468
SubstitutionList(), Args,
463469
TAI->getNormalBB(), TAI->getErrorBB());
464-
else
470+
else {
465471
NAI = Builder.createApply(AI.getLoc(), FRI, SubstitutionList(), Args,
466472
cast<ApplyInst>(AI)->isNonThrowing());
473+
assert(FullApplySite::isa(NAI).getSubstCalleeType()->getAllResultsType() ==
474+
AI.getSubstCalleeType()->getAllResultsType() &&
475+
"Function types should be the same");
476+
}
467477
return NAI;
468478
}
469479

test/SILOptimizer/sil_combine.sil

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,6 +1215,52 @@ bb0(%0 : $*B, %1 : $B, %2 : $Builtin.Int1):
12151215
return %6 : $()
12161216
}
12171217

1218+
// Check that convert_function simplifications are not applied in certain cases.
1219+
@objc class MyNSObj { }
1220+
1221+
class AnotherClass : MyNSObj { }
1222+
1223+
sil @MyNSObj_self : $@convention(method) (@guaranteed MyNSObj) -> @owned MyNSObj
1224+
1225+
sil shared [transparent] [serializable] [reabstraction_thunk] @reabstraction_thunk1 : $@convention(thin) (@in (), @owned @callee_owned () -> @owned AnotherClass) -> @out AnotherClass {
1226+
bb0(%0 : $*AnotherClass, %1 : $*(), %2 : $@callee_owned () -> @owned AnotherClass):
1227+
%3 = apply %2() : $@callee_owned () -> @owned AnotherClass
1228+
store %3 to %0 : $*AnotherClass
1229+
%5 = tuple ()
1230+
return %5 : $()
1231+
}
1232+
1233+
// @nonobjc curry thunk of MyNSObj.self()
1234+
sil shared [serializable] [thunk] @curry_thunk_for_MyNSObj_self : $@convention(thin) (@owned MyNSObj) -> @owned @callee_owned () -> @owned MyNSObj {
1235+
bb0(%0 : $MyNSObj):
1236+
// function_ref @nonobjc MyNSObj.self()
1237+
%1 = function_ref @MyNSObj_self : $@convention(method) (@guaranteed MyNSObj) -> @owned MyNSObj
1238+
%2 = partial_apply %1(%0) : $@convention(method) (@guaranteed MyNSObj) -> @owned MyNSObj
1239+
return %2 : $@callee_owned () -> @owned MyNSObj
1240+
}
1241+
1242+
// Check that convert_function is not eliminated if the result type of the converted function is different from the apply result type.
1243+
// CHECK-LABEL: sil {{.*}} @do_not_peephole_convert_function : $@convention(thin) (@in AnotherClass) -> @out @callee_owned (@in ()) -> @out AnotherClass {
1244+
// CHECK: [[CF:%[0-9]+]] = convert_function
1245+
// CHECK: [[APPLY:%[0-9]+]] = apply
1246+
// CHECK: [[FUN:%[0-9]+]] = function_ref
1247+
// CHECK: [[CF:%[0-9]+]] = partial_apply [[FUN]]([[APPLY]])
1248+
// CHECK: // end sil function 'do_not_peephole_convert_function'
1249+
sil shared [transparent] [reabstraction_thunk] @do_not_peephole_convert_function : $@convention(thin) (@in AnotherClass) -> @out @callee_owned (@in ()) -> @out AnotherClass {
1250+
bb0(%0 : $*@callee_owned (@in ()) -> @out AnotherClass, %1 : $*AnotherClass):
1251+
// function_ref @nonobjc curry thunk of MyNSObj.self()
1252+
%2 = function_ref @curry_thunk_for_MyNSObj_self : $@convention(thin) (@owned MyNSObj) -> @owned @callee_owned () -> @owned MyNSObj
1253+
%3 = convert_function %2 : $@convention(thin) (@owned MyNSObj) -> @owned @callee_owned () -> @owned MyNSObj to $@convention(thin) (@owned AnotherClass) -> @owned @callee_owned () -> @owned AnotherClass
1254+
%5 = load %1 : $*AnotherClass
1255+
%6 = apply %3(%5) : $@convention(thin) (@owned AnotherClass) -> @owned @callee_owned () -> @owned AnotherClass
1256+
// function_ref thunk for @callee_owned () -> (@owned AnotherClass)
1257+
%7 = function_ref @reabstraction_thunk1 : $@convention(thin) (@in (), @owned @callee_owned () -> @owned AnotherClass) -> @out AnotherClass
1258+
%8 = partial_apply %7(%6) : $@convention(thin) (@in (), @owned @callee_owned () -> @owned AnotherClass) -> @out AnotherClass
1259+
store %8 to %0 : $*@callee_owned (@in ()) -> @out AnotherClass
1260+
%10 = tuple ()
1261+
return %10 : $()
1262+
} // end sil function 'do_not_peephole_convert_function'
1263+
12181264
// CHECK-LABEL: sil @upcast_formation : $@convention(thin) (@inout E, E, @inout B) -> B {
12191265
// CHECK: bb0
12201266
// CHECK-NEXT: upcast

0 commit comments

Comments
 (0)