Skip to content

Commit 8a62b66

Browse files
authored
Merge pull request #12765 from aschwaighofer/fix_sil_combine_callee_guaranteed
2 parents cb24a41 + 1c67e1e commit 8a62b66

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-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: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,14 +334,16 @@ 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.emitDestroyValueOperation(PAI->getLoc(), PAI);
338339
Builder.setInsertionPoint(AI.getInstruction());
339340
} else {
340341
// Release the non-consumed parameters.
341342
for (auto Arg : ToBeReleasedArgs) {
342343
Builder.emitDestroyValueOperation(PAI->getLoc(), Arg);
343344
}
344-
Builder.createStrongRelease(AI.getLoc(), PAI, Builder.getDefaultAtomicity());
345+
if (!PAI->hasCalleeGuaranteedContext())
346+
Builder.emitDestroyValueOperation(PAI->getLoc(), PAI);
345347
}
346348

347349
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)