Skip to content

Commit b5fab61

Browse files
committed
SILCombiner: Fix partial_apply optimization of @callee_guaranteed
closures @callee_guaranteed closure contexts must not be released when replacing a closure application. SR-5441 rdar://33255593
1 parent 3e45eb7 commit b5fab61

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1914,6 +1914,9 @@ class PartialApplyInst
19141914
CanSILFunctionType getFunctionType() const {
19151915
return getType().castTo<SILFunctionType>();
19161916
}
1917+
bool hasCalleeGuaranteedContext() const {
1918+
return getType().castTo<SILFunctionType>()->isCalleeGuaranteed();
1919+
}
19171920
};
19181921

19191922
//===----------------------------------------------------------------------===//

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,14 +334,18 @@ bool PartialApplyCombiner::processSingleApply(FullApplySite AI) {
334334
for (auto Arg : ToBeReleasedArgs) {
335335
Builder.emitDestroyValueOperation(PAI->getLoc(), Arg);
336336
}
337-
Builder.createStrongRelease(AI.getLoc(), PAI, Builder.getDefaultAtomicity());
337+
if (!PAI->hasCalleeGuaranteedContext())
338+
Builder.createStrongRelease(AI.getLoc(), PAI,
339+
Builder.getDefaultAtomicity());
338340
Builder.setInsertionPoint(AI.getInstruction());
339341
} else {
340342
// Release the non-consumed parameters.
341343
for (auto Arg : ToBeReleasedArgs) {
342344
Builder.emitDestroyValueOperation(PAI->getLoc(), Arg);
343345
}
344-
Builder.createStrongRelease(AI.getLoc(), PAI, Builder.getDefaultAtomicity());
346+
if (!PAI->hasCalleeGuaranteedContext())
347+
Builder.createStrongRelease(AI.getLoc(), PAI,
348+
Builder.getDefaultAtomicity());
345349
}
346350

347351
if (auto apply = dyn_cast<ApplyInst>(AI))

test/SILOptimizer/sil_combine_apply.sil

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,3 +437,29 @@ bb99:
437437
%empty = tuple ()
438438
return %empty : $()
439439
}
440+
441+
class C {}
442+
443+
sil @guaranteed_closure : $@convention(thin) (@guaranteed C) -> ()
444+
445+
// CHECK-LABEL: sil @test_guaranteed_closure
446+
// CHECK: bb0([[ARG:%.*]] : $C):
447+
// CHECK: strong_retain [[ARG]]
448+
// CHECK: [[F:%.*]] = function_ref @guaranteed_closure
449+
// CHECK: [[C:%.*]] = partial_apply [callee_guaranteed] [[F]]([[ARG]])
450+
// CHECK: strong_retain [[ARG]]
451+
// CHECK: apply [[F]]
452+
// Don't release the closure context -- it is @callee_guaranteed.
453+
// CHECK-NOT: strong_release [[C]] : $@callee_guaranteed () -> ()
454+
// CHECK: strong_release [[ARG]]
455+
// CHECK-NOT: strong_release [[C]] : $@callee_guaranteed () -> ()
456+
// CHECK: return [[C]]
457+
458+
sil @test_guaranteed_closure : $@convention(thin) (@guaranteed C) -> @owned @callee_guaranteed () -> () {
459+
bb0(%0: $C):
460+
strong_retain %0 : $C
461+
%closure_fun = function_ref @guaranteed_closure : $@convention(thin) (@guaranteed C) -> ()
462+
%closure = partial_apply [callee_guaranteed] %closure_fun(%0) : $@convention(thin) (@guaranteed C) -> ()
463+
apply %closure() : $@callee_guaranteed () -> ()
464+
return %closure : $@callee_guaranteed () -> ()
465+
}

0 commit comments

Comments
 (0)