diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp index 977a2f7dd7355..634468033871e 100644 --- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp @@ -83,8 +83,10 @@ SILInstruction *SILCombiner::visitPartialApplyInst(PartialApplyInst *PAI) { return nullptr; // partial_apply without any substitutions or arguments is just a - // thin_to_thick_function. - if (!PAI->hasSubstitutions() && (PAI->getNumArguments() == 0)) { + // thin_to_thick_function. thin_to_thick_function supports only thin operands. + if (!PAI->hasSubstitutions() && (PAI->getNumArguments() == 0) && + PAI->getSubstCalleeType()->getRepresentation() == + SILFunctionTypeRepresentation::Thin) { if (!PAI->isOnStack()) return Builder.createThinToThickFunction(PAI->getLoc(), PAI->getCallee(), PAI->getType()); diff --git a/test/AutoDiff/compiler_crashers_fixed/sr12548-siloptimizer-rewrite-partial-apply-convention-method.swift b/test/AutoDiff/compiler_crashers_fixed/sr12548-siloptimizer-rewrite-partial-apply-convention-method.swift new file mode 100644 index 0000000000000..007b4b997dfce --- /dev/null +++ b/test/AutoDiff/compiler_crashers_fixed/sr12548-siloptimizer-rewrite-partial-apply-convention-method.swift @@ -0,0 +1,27 @@ +// RUN: %target-build-swift -O %s + +// SR-12548: SIL verification error regarding +// `CapturePropagation::rewritePartialApply` for `partial_apply` with +// `@convention(method)` callee. + +import _Differentiation + +protocol Protocol: Differentiable { + @differentiable + func method() -> Self +} + +extension Protocol { + @differentiable + func method() -> Self { self } +} + +struct Struct: Protocol {} + +let _: @differentiable (Struct) -> Struct = { $0.method() } + +// SIL verification failed: operand of thin_to_thick_function must be thin: opFTy->getRepresentation() == SILFunctionType::Representation::Thin +// Verifying instruction: +// // function_ref specialized Protocol.method() +// %5 = function_ref @$s7crasher8ProtocolPAAE6methodxyFAA6StructV_TG5 : $@convention(method) (@in_guaranteed Struct) -> @out Struct // user: %6 +// -> %6 = thin_to_thick_function %5 : $@convention(method) (@in_guaranteed Struct) -> @out Struct to $@callee_guaranteed (@in_guaranteed Struct) -> @out Struct // user: %11 diff --git a/test/SILOptimizer/sil_combine_apply.sil b/test/SILOptimizer/sil_combine_apply.sil index 438af89481949..e00fbd92d6533 100644 --- a/test/SILOptimizer/sil_combine_apply.sil +++ b/test/SILOptimizer/sil_combine_apply.sil @@ -974,3 +974,20 @@ bb0(%0: $*FakeProtocol): %r = tuple () return %r : $() } + +// Test `partial_apply` with a `@convention(method)` callee. +// Rewriting `partial_apply` to `thin_to_thick_function` is not okay because +// `thin_to_thick_function` supports only `@convention(thin)` operands. + +sil @method : $@convention(method) (Int32) -> () + +sil @test_partial_apply_method : $@convention(thin) () -> @owned @callee_owned (Int32) -> () { + %1 = function_ref @method : $@convention(method) (Int32) -> () + %2 = partial_apply %1() : $@convention(method) (Int32) -> () + return %2 : $@callee_owned (Int32) -> () +} + +// CHECK-LABEL: sil @test_partial_apply_method +// CHECK: [[FN:%.*]] = function_ref @method +// CHECK-NEXT: partial_apply [[FN]]() +// CHECK-NEXT: return