Merge pull request #14832 from gottesmm/swift-4.1-branchrdar37820485
[arc] An apply of a callee_guaranteed thick function is a "guaranteed…
diff --git a/lib/SILOptimizer/Analysis/ARCAnalysis.cpp b/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
index ddf50c8..c88021b 100644
--- a/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
@@ -441,8 +441,17 @@
FullApplySite FAS(User);
- // Ok, we have a full apply site. If the apply has no arguments, we don't need
- // to worry about any guaranteed parameters.
+ // Ok, we have a full apply site. Check if the callee is callee_guaranteed. In
+ // such a case, if we can not prove no alias, we need to be conservative and
+ // return true.
+ CanSILFunctionType FType = FAS.getSubstCalleeType();
+ if (FType->isCalleeGuaranteed() && !AA->isNoAlias(FAS.getCallee(), Ptr)) {
+ return true;
+ }
+
+ // Ok, we have a full apply site and our callee is a normal use. Thus if the
+ // apply does not have any normal arguments, we don't need to worry about any
+ // guaranteed parameters and return early.
if (!FAS.getNumArguments())
return false;
@@ -450,7 +459,6 @@
// iterate through the function parameters. If any of the parameters are
// guaranteed, attempt to prove that the passed in parameter cannot alias
// Ptr. If we fail, return true.
- CanSILFunctionType FType = FAS.getSubstCalleeType();
auto Params = FType->getParameters();
for (unsigned i : indices(Params)) {
if (!Params[i].isGuaranteed())
diff --git a/test/SILOptimizer/arcsequenceopts.sil b/test/SILOptimizer/arcsequenceopts.sil
index 1ba2037..c1ad811 100644
--- a/test/SILOptimizer/arcsequenceopts.sil
+++ b/test/SILOptimizer/arcsequenceopts.sil
@@ -2146,3 +2146,20 @@
strong_release %1 : $Builtin.NativeObject
return undef : $()
}
+
+// Make sure that we treat applications of callee_guaranteed functions as a
+// guaranteed use of the function object.
+//
+// CHECK-LABEL: sil @test_callee_guaranteed_is_treated_as_guaranteed : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () {
+// CHECK: strong_retain
+// CHECK: apply
+// CHECK: strong_release
+// CHECK: } // end sil function 'test_callee_guaranteed_is_treated_as_guaranteed'
+sil @test_callee_guaranteed_is_treated_as_guaranteed : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () {
+bb0(%0 : $@callee_guaranteed () -> ()):
+ strong_retain %0 : $@callee_guaranteed () -> ()
+ apply %0() : $@callee_guaranteed () -> ()
+ strong_release %0 : $@callee_guaranteed () -> ()
+ %9999 = tuple()
+ return %9999 : $()
+}