Merge pull request #11261 from gottesmm/swift-4.0-branch_rdar33595317_1
[4.0] [sil-combine] Make sure that (apply (partial_apply)) -> (apply') bail…
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index 99788a0..38b12c0 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -151,14 +151,15 @@
// Emit a destroy value for each captured closure argument.
ArrayRef<SILParameterInfo> Params = PAITy->getParameters();
auto Args = PAI->getArguments();
- unsigned Delta = Params.size() - Args.size();
+ Params = Params.drop_front(Params.size() - Args.size());
llvm::SmallVector<std::pair<SILValue, unsigned>, 8> ArgsToHandle;
- for (unsigned AI = 0, AE = Args.size(); AI != AE; ++AI) {
- SILValue Arg = Args[AI];
- SILParameterInfo Param = Params[AI + Delta];
+ for (unsigned i : indices(Args)) {
+ SILValue Arg = Args[i];
+ SILParameterInfo Param = Params[i];
if (Param.isIndirectMutating())
continue;
+
// Create a temporary and copy the argument into it, if:
// - the argument stems from an alloc_stack
// - the argument is consumed by the callee and is indirect
@@ -166,10 +167,18 @@
if (isa<AllocStackInst>(Arg)
|| (Param.isConsumed()
&& PAI->getSubstCalleeConv().isSILIndirect(Param))) {
+ // If the argument has a dependent type, then we can not create a
+ // temporary for it at the beginning of the function, so we must bail.
+ //
+ // TODO: This is because we are inserting alloc_stack at the beginning/end
+ // of functions where the dependent type may not exist yet.
+ if (Arg->getType().hasOpenedExistential())
+ return false;
+
// If the temporary is non-trivial, we need to release it later.
if (!Arg->getType().isTrivial(PAI->getModule()))
needsReleases = true;
- ArgsToHandle.push_back(std::make_pair(Arg, AI));
+ ArgsToHandle.push_back(std::make_pair(Arg, i));
}
}
diff --git a/test/SILOptimizer/sil_combine_apply.sil b/test/SILOptimizer/sil_combine_apply.sil
index 0c85a11..2bf1e6f 100644
--- a/test/SILOptimizer/sil_combine_apply.sil
+++ b/test/SILOptimizer/sil_combine_apply.sil
@@ -11,6 +11,10 @@
protocol Error {}
+protocol SwiftP {
+ func foo()
+}
+
/////////////////////////////////
// Tests for SILCombinerApply. //
/////////////////////////////////
@@ -235,10 +239,6 @@
throw %5 : $Error
}
-protocol SwiftP {
- func foo()
-}
-
// Make sure that we do not optimize this case. If we do optimize this case,
// given the current algorithm which puts alloc_stack at the beginning/end of
// the function, we will have a fatal error.
@@ -285,4 +285,27 @@
%a1 = apply %pa(%0) : $@callee_owned (@in T) -> ()
%r = tuple ()
return %r : $()
+}
+
+// Today when we optimize (apply (partial_apply)) -> apply, we can not handle
+// dependent types since the algorithm attempts to create an alloc_stack at the
+// beginning/end of the function. In such a case, the dependent type may not be
+// alive at that point, so the compiler will crash. This test ensures that we do
+// not optimize this case.
+//
+// CHECK-LABEL: sil @sil_combine_applied_partialapply_to_apply_with_dependent_type : $@convention(thin) (@in SwiftP) -> () {
+// CHECK: [[PAI:%.*]] = partial_apply
+// CHECK: apply [[PAI]]
+sil @sil_combine_applied_partialapply_to_apply_with_dependent_type : $@convention(thin) (@in SwiftP) -> () {
+bb0(%0 : $*SwiftP):
+ %0b = alloc_stack $SwiftP
+ %1 = open_existential_addr mutable_access %0b : $*SwiftP to $*@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP
+ %2 = witness_method $@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP, #SwiftP.foo!1, %1 : $*@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP : $@convention(witness_method) <τ_0_0 where τ_0_0 : SwiftP> (@in_guaranteed τ_0_0) -> ()
+ %0c = alloc_stack $@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP
+ %3 = partial_apply %2<@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP>(%0c) : $@convention(witness_method) <τ_0_0 where τ_0_0 : SwiftP> (@in_guaranteed τ_0_0) -> ()
+ dealloc_stack %0c : $*@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP
+ dealloc_stack %0b : $*SwiftP
+ %4 = apply %3() : $@callee_owned () -> ()
+ %9999 = tuple()
+ return %9999 : $()
}
\ No newline at end of file