// RUN: %target-swift-frontend -parse-stdlib -Xllvm -sil-print-types -emit-silgen %s | %FileCheck %s import _Differentiation import Swift @_silgen_name("f_direct_arity1") func f_direct_arity1(_ x: Float) -> Float { x } @_silgen_name("f_direct_arity1_jvp") func f_direct_arity1_jvp(_ x: Float) -> (Float, (Float) -> Float) { (x, { $0 }) } @_silgen_name("f_direct_arity1_vjp") func f_direct_arity1_vjp(_ x: Float) -> (Float, (Float) -> Float) { (x, { $0 }) } @_silgen_name("f_direct_arity2") func f_direct_arity2(_ x: Float, _ y: Float) -> Float { x } @_silgen_name("f_indirect_arity1") func f_indirect_arity1(_ x: T) -> T { x } // MARK: - applyDerivative @_silgen_name("applyDerivative_f_direct_arity1_jvp") func applyDerivative_f1_jvp(_ x: Float) -> (Float, (Float) -> Float) { return Builtin.applyDerivative_jvp(f_direct_arity1, x) } // CHECK-LABEL: sil{{.*}}@applyDerivative_f_direct_arity1_jvp // CHECK: bb0([[X:%.*]] : $Float): // CHECK: [[D:%.*]] = differentiable_function_extract [jvp] // CHECK: [[D_RESULT:%.*]] = apply [[D]]([[X]]) // CHECK: ([[D_RESULT_0:%.*]], [[D_RESULT_1:%.*]]) = destructure_tuple [[D_RESULT]] // CHECK: [[D_RESULT_RETUPLED:%.*]] = tuple ([[D_RESULT_0]] : {{.*}}, [[D_RESULT_1]] : {{.*}}) // CHECK: return [[D_RESULT_RETUPLED]] @_silgen_name("applyDerivative_f_direct_arity1_vjp") func applyDerivative_f1_vjp(_ x: Float) -> (Float, (Float) -> Float) { return Builtin.applyDerivative_vjp(f_direct_arity1, x) } // CHECK-LABEL: sil{{.*}}@applyDerivative_f_direct_arity1_vjp // CHECK: bb0([[X:%.*]] : $Float): // CHECK: [[D:%.*]] = differentiable_function_extract [vjp] // CHECK: [[D_RESULT:%.*]] = apply [[D]]([[X]]) // CHECK: ([[D_RESULT_0:%.*]], [[D_RESULT_1:%.*]]) = destructure_tuple [[D_RESULT]] // CHECK: [[D_RESULT_RETUPLED:%.*]] = tuple ([[D_RESULT_0]] : {{.*}}, [[D_RESULT_1]] : {{.*}}) // CHECK: return [[D_RESULT_RETUPLED]] @_silgen_name("applyDerivative_f_direct_arity2_vjp") func applyDerivative_f1_vjp(_ x: Float, _ y: Float) -> (Float, (Float) -> (Float, Float)) { return Builtin.applyDerivative_vjp_arity2(f_direct_arity2, x, y) } // CHECK-LABEL: sil{{.*}}@applyDerivative_f_direct_arity2_vjp // CHECK: bb0([[X:%.*]] : $Float, [[Y:%.*]] : $Float): // CHECK: [[D:%.*]] = differentiable_function_extract [vjp] // CHECK: [[D_RESULT:%.*]] = apply [[D]]([[X]], [[Y]]) // CHECK: ([[D_RESULT_0:%.*]], [[D_RESULT_1:%.*]]) = destructure_tuple [[D_RESULT]] // CHECK: [[D_RESULT_RETUPLED:%.*]] = tuple ([[D_RESULT_0]] : {{.*}}, [[D_RESULT_1]] : {{.*}}) // CHECK: return [[D_RESULT_RETUPLED]] @_silgen_name("applyDerivative_f_indirect_arity1_vjp") func applyDerivative_f1_vjp(t0: T) -> (T, (T.TangentVector) -> T.TangentVector) { return Builtin.applyDerivative_vjp(f_indirect_arity1, t0) } // CHECK-LABEL: sil{{.*}}@applyDerivative_f_indirect_arity1_vjp // CHECK: bb0([[ORIG_RESULT_OUT_PARAM:%.*]] : $*T, [[X:%.]] : $*T): // CHECK: [[D:%.*]] = differentiable_function_extract [vjp] // CHECK: [[D_RESULT_BUFFER:%.*]] = alloc_stack $(T, @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) // CHECK: [[D_RESULT_BUFFER_0_FOR_STORE:%.*]] = tuple_element_addr [[D_RESULT_BUFFER]] : ${{.*}}, 0 // CHECK: [[D_RESULT:%.*]] = apply [[D]]([[D_RESULT_BUFFER_0_FOR_STORE]], [[X]]) // CHECK: [[D_RESULT_BUFFER_1_FOR_STORE:%.*]] = tuple_element_addr [[D_RESULT_BUFFER]] : ${{.*}}, 1 // CHECK: store [[D_RESULT]] to [init] [[D_RESULT_BUFFER_1_FOR_STORE]] // CHECK: [[D_RESULT_BUFFER_0_FOR_LOAD:%.*]] = tuple_element_addr [[D_RESULT_BUFFER]] : ${{.*}}, 0 // CHECK: [[D_RESULT_BUFFER_1_FOR_LOAD:%.*]] = tuple_element_addr [[D_RESULT_BUFFER]] : ${{.*}}, 1 // CHECK: [[PULLBACK:%.*]] = load [take] [[D_RESULT_BUFFER_1_FOR_LOAD]] // CHECK: copy_addr [take] [[D_RESULT_BUFFER_0_FOR_LOAD]] to [init] [[ORIG_RESULT_OUT_PARAM]] // CHECK: return [[PULLBACK]] @_silgen_name("test_context_builtins_with_type") func test_context_builtins_with_type(t: T) { let context = Builtin.autoDiffCreateLinearMapContextWithType(T.self) let topLevelSubctxAddr = Builtin.autoDiffProjectTopLevelSubcontext(context) UnsafeMutableRawPointer(topLevelSubctxAddr).storeBytes(of: t, as: T.self) let newBuffer = Builtin.autoDiffAllocateSubcontextWithType(context, T.self) UnsafeMutableRawPointer(newBuffer).storeBytes(of: t, as: T.self) } // CHECK-LABEL: sil{{.*}}@test_context_builtins_with_type : $@convention(thin) (@in_guaranteed T) -> () { // CHECK: bb0({{%.*}} : $*T): // CHECK: [[CTX:%.*]] = builtin "autoDiffCreateLinearMapContextWithType"({{%.*}} : $@thick T.Type) : $Builtin.NativeObject // CHECK: [[CTX_LIFETIME:%.*]] = move_value [lexical] [var_decl] [[CTX]] // CHECK: [[BORROWED_CTX:%.*]] = begin_borrow [[CTX_LIFETIME]] // CHECK: [[BUF:%.*]] = builtin "autoDiffProjectTopLevelSubcontext"([[BORROWED_CTX]] : $Builtin.NativeObject) : $Builtin.RawPointer // CHECK: [[BORROWED_CTX:%.*]] = begin_borrow [[CTX_LIFETIME]] // CHECK: [[BUF:%.*]] = builtin "autoDiffAllocateSubcontextWithType"([[BORROWED_CTX]] : $Builtin.NativeObject, {{.*}} : $@thick T.Type) : $Builtin.RawPointer // CHECK: destroy_value [[CTX_LIFETIME]]