-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Closed
Labels
SILOptimizerArea → compiler: SIL optimization passesArea → compiler: SIL optimization passesbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.A deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselfThe Swift compiler itself
Description
| Previous ID | SR-12548 |
| Radar | rdar://problem/62201645 |
| Original Reporter | @dan-zheng |
| Type | Bug |
| Status | Closed |
| Resolution | Done |
Additional Detail from JIRA
| Votes | 0 |
| Component/s | Compiler |
| Labels | Bug, SILOptimizer |
| Assignee | @dan-zheng |
| Priority | Medium |
md5: b55fdb79390cc22b94c51ec8555c6e04
Issue Description:
SILCombiner::visitPartialApplyInst rewrites the following SIL:
%1 = function_ref @method_func : $@convention(method) (Int32) -> ()
%2 = partial_apply %1() : $@convention(method) (Int32) -> ()Into the following SIL, which fails verification:
%0 = function_ref @method_func : $@convention(method) (Int32) -> ()
%1 = thin_to_thick_function %0 : $@convention(method) (Int32) -> () to $@callee_owned (Int32) -> ()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: %11Fix ideas:
-
Disable
SILCombiner::visitPartialApplyInstfor non-@convention(thin)callees.- Other code paths that may construct
thin_to_thick_functionwith@convention(method)operands (e.g.CapturePropagation::rewritePartialApply) should be updated similarly.
- Other code paths that may construct
-
Relax verification to allow
thin_to_thick_functionwith@convention(method)operands. I don't know if this is valid.
SIL reproducer:
import Swift
import Builtin
sil @method_func : $@convention(method) (Int32) -> ()
sil @test_capture_propagation_method_callee : $@convention(thin) () -> @owned @callee_owned (Int32) -> () {
%1 = function_ref @method_func : $@convention(method) (Int32) -> ()
%2 = partial_apply %1() : $@convention(method) (Int32) -> ()
return %2 : $@callee_owned (Int32) -> ()
}Swift reproducer (via SIL generated by differentiation transform):
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() }$ swiftc -O crasher.swift
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
%11 = differentiable_function [parameters 0] %6 : $@callee_guaranteed (@in_guaranteed Struct) -> @out Struct with_derivative {%8 : $@callee_guaranteed (@in_guaranteed Struct) -> (@out Struct, @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <Struct.TangentVector, Struct.TangentVector>), %10 : $@callee_guaranteed (@in_guaranteed Struct) -> (@out Struct, @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <Struct.TangentVector, Struct.TangentVector>)} // users: %18, %16, %13, %12
In function:
// AD__$s7crasherAA6StructVACcfU___vjp_src_0_wrt_0
sil private @AD__$s7crasherAA6StructVACcfU___vjp_src_0_wrt_0 : $@convention(thin) (Struct) -> (Struct, @owned @callee_guaranteed (Struct.TangentVector) -> Struct.TangentVector) {
// %0 // users: %4, %1
bb0(%0 : $Struct):
debug_value %0 : $Struct, let, name "$0", argno 1 // id: %1
%2 = alloc_stack $Struct // users: %26, %20
%3 = alloc_stack $Struct // users: %4, %24, %20
store %0 to %3 : $*Struct // id: %4
// 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
%7 = differentiability_witness_function [jvp] [parameters 0] [results 0] <Self where Self : Protocol> @$s7crasher8ProtocolPAAE6methodxyF : $@convention(method) <Self where Self : Protocol> (@in_guaranteed Self) -> @out Self // user: %8
%8 = partial_apply [callee_guaranteed] %7<Struct>() : $@convention(method) <τ_0_0 where τ_0_0 : Protocol> (@in_guaranteed τ_0_0) -> (@out τ_0_0, @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0.TangentVector, τ_0_0.TangentVector>) // user: %11
%9 = differentiability_witness_function [vjp] [parameters 0] [results 0] <Self where Self : Protocol> @$s7crasher8ProtocolPAAE6methodxyF : $@convention(method) <Self where Self : Protocol> (@in_guaranteed Self) -> @out Self // user: %10
%10 = partial_apply [callee_guaranteed] %9<Struct>() : $@convention(method) <τ_0_0 where τ_0_0 : Protocol> (@in_guaranteed τ_0_0) -> (@out τ_0_0, @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0.TangentVector, τ_0_0.TangentVector>) // user: %11
%11 = differentiable_function [parameters 0] %6 : $@callee_guaranteed (@in_guaranteed Struct) -> @out Struct with_derivative {%8 : $@callee_guaranteed (@in_guaranteed Struct) -> (@out Struct, @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <Struct.TangentVector, Struct.TangentVector>), %10 : $@callee_guaranteed (@in_guaranteed Struct) -> (@out Struct, @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <Struct.TangentVector, Struct.TangentVector>)} // users: %18, %16, %13, %12
%12 = differentiable_function_extract [vjp] %11 : $@differentiable @callee_guaranteed (@in_guaranteed Struct) -> @out Struct // users: %21, %14, %20
%13 = differentiable_function_extract [original] %11 : $@differentiable @callee_guaranteed (@in_guaranteed Struct) -> @out Struct // user: %15
strong_retain %12 : $@callee_guaranteed (@in_guaranteed Struct) -> (@out Struct, @owned @callee_guaranteed (@in_guaranteed Struct.TangentVector) -> @out Struct.TangentVector) // id: %14
strong_release %13 : $@callee_guaranteed (@in_guaranteed Struct) -> @out Struct // id: %15
%16 = differentiable_function_extract [jvp] %11 : $@differentiable @callee_guaranteed (@in_guaranteed Struct) -> @out Struct // user: %17
strong_release %16 : $@callee_guaranteed (@in_guaranteed Struct) -> (@out Struct, @owned @callee_guaranteed (@in_guaranteed Struct.TangentVector) -> @out Struct.TangentVector) // id: %17
%18 = differentiable_function_extract [vjp] %11 : $@differentiable @callee_guaranteed (@in_guaranteed Struct) -> @out Struct // user: %19
strong_release %18 : $@callee_guaranteed (@in_guaranteed Struct) -> (@out Struct, @owned @callee_guaranteed (@in_guaranteed Struct.TangentVector) -> @out Struct.TangentVector) // id: %19
%20 = apply %12(%2, %3) : $@callee_guaranteed (@in_guaranteed Struct) -> (@out Struct, @owned @callee_guaranteed (@in_guaranteed Struct.TangentVector) -> @out Struct.TangentVector) // user: %23
strong_release %12 : $@callee_guaranteed (@in_guaranteed Struct) -> (@out Struct, @owned @callee_guaranteed (@in_guaranteed Struct.TangentVector) -> @out Struct.TangentVector) // id: %21
// function_ref thunk for @escaping @callee_guaranteed (@in_guaranteed Struct.TangentVector) -> (@out Struct.TangentVector)
%22 = function_ref @$s7crasher6StructV13TangentVectorVAEIegnr_A2EIegyd_TR : $@convention(thin) (Struct.TangentVector, @guaranteed @callee_guaranteed (@in_guaranteed Struct.TangentVector) -> @out Struct.TangentVector) -> Struct.TangentVector // user: %23
%23 = partial_apply [callee_guaranteed] %22(%20) : $@convention(thin) (Struct.TangentVector, @guaranteed @callee_guaranteed (@in_guaranteed Struct.TangentVector) -> @out Struct.TangentVector) -> Struct.TangentVector // user: %27
dealloc_stack %3 : $*Struct // id: %24
%25 = struct $Struct () // user: %30
dealloc_stack %2 : $*Struct // id: %26
%27 = struct $_AD__$s7crasherAA6StructVACcfU__bb0__PB__src_0_wrt_0 (%23 : $@callee_guaranteed (Struct.TangentVector) -> Struct.TangentVector) // user: %29
// function_ref AD__$s7crasherAA6StructVACcfU___pullback_src_0_wrt_0
%28 = function_ref @AD__$s7crasherAA6StructVACcfU___pullback_src_0_wrt_0 : $@convention(thin) (Struct.TangentVector, @owned _AD__$s7crasherAA6StructVACcfU__bb0__PB__src_0_wrt_0) -> Struct.TangentVector // user: %29
%29 = partial_apply [callee_guaranteed] %28(%27) : $@convention(thin) (Struct.TangentVector, @owned _AD__$s7crasherAA6StructVACcfU__bb0__PB__src_0_wrt_0) -> Struct.TangentVector // user: %30
%30 = tuple (%25 : $Struct, %29 : $@callee_guaranteed (Struct.TangentVector) -> Struct.TangentVector) // user: %31
return %30 : $(Struct, @callee_guaranteed (Struct.TangentVector) -> Struct.TangentVector) // id: %31
} // end sil function 'AD__$s7crasherAA6StructVACcfU___vjp_src_0_wrt_0'Metadata
Metadata
Assignees
Labels
SILOptimizerArea → compiler: SIL optimization passesArea → compiler: SIL optimization passesbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.A deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselfThe Swift compiler itself