mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Also, fix and enable `IRGen/lto_autolink` for all non-Wasm targets and `IRGen/static_initializer` for aarch64. This should get [the community Android CI](https://ci-external.swift.org/job/oss-swift-RA-linux-ubuntu-24.04-android-build/) green [again](https://ci-external.swift.org/job/oss-swift-RA-linux-ubuntu-24.04-android-arm64/).
92 lines
3.3 KiB
Swift
92 lines
3.3 KiB
Swift
// VJP inlining tests.
|
|
|
|
// RUN: %target-swift-frontend -emit-sil -O -verify -Xllvm -debug-only=sil-inliner %s 2>&1 | %FileCheck %s
|
|
|
|
// REQUIRES: asserts
|
|
// REQUIRES: swift_in_compiler
|
|
// UNSUPPORTED: OS=windows-msvc
|
|
|
|
import _Differentiation
|
|
#if canImport(Glibc)
|
|
import Glibc
|
|
#elseif canImport(Android)
|
|
import Android
|
|
#else
|
|
import Foundation
|
|
#endif
|
|
|
|
// =============================================================== //
|
|
// VJPs with control-flow are inlined into non-VJP callers
|
|
// =============================================================== //
|
|
@differentiable(reverse)
|
|
func with_control_flow(_ x: Float) -> Float {
|
|
if (x > 0) {
|
|
return sin(x) * cos(x)
|
|
} else {
|
|
return sin(x) + cos(x)
|
|
}
|
|
}
|
|
|
|
@inline(never)
|
|
@_silgen_name("caller_of_with_control_flow")
|
|
func caller_of_with_control_flow(x: Float) -> Float {
|
|
gradient(at: x, of: with_control_flow)
|
|
}
|
|
// CHECK-LABEL: decision {{.*}} $s12vjp_inlining17with_control_flowyS2fFTJrSpSr
|
|
// CHECK-NEXT: "reverse-mode derivative of vjp_inlining.with_control_flow(_:)" inlined into "reverse-mode derivative of vjp_inlining.wrapperOnWithControlFlow(x:)"
|
|
|
|
// =============================================================== //
|
|
// VJPs with control-flow are inlined into VJP callers
|
|
// =============================================================== //
|
|
|
|
@differentiable(reverse)
|
|
func wrapperOnWithControlFlow(x: Float) -> Float {
|
|
return with_control_flow(x)
|
|
}
|
|
// CHECK-LABEL: decision {{.*}} $s12vjp_inlining17with_control_flowyS2fFTJrSpSr
|
|
// CHECK-NEXT: "reverse-mode derivative of vjp_inlining.with_control_flow(_:)" inlined into "caller_of_with_control_flow"
|
|
|
|
// =============================================================== //
|
|
// VJPs without control-flow are not inlined into non-VJP callers
|
|
// =============================================================== //
|
|
@differentiable(reverse)
|
|
func simple(x: Float) -> Float {
|
|
let a = x * x;
|
|
let b = x + x;
|
|
let c = x * a;
|
|
let d = a + b;
|
|
let e = b * c;
|
|
|
|
return a * b / c + d - e ;
|
|
}
|
|
|
|
@inline(never)
|
|
@_silgen_name("caller_of_simple")
|
|
func caller_of_simple(x: Float) -> Float {
|
|
gradient(at: Float(4), of: simple)
|
|
}
|
|
// CHECK-NOT: "reverse-mode derivative of vjp_inlining.simple(x:)" inlined into "caller_of_simple"
|
|
|
|
// ============================================================================ //
|
|
// VJPs without control-flow are not inlined into VJP callers with control-flow
|
|
// ============================================================================ //
|
|
@differentiable(reverse)
|
|
func wrapperWithControlFlowOnSimple(x: Float) -> Float {
|
|
if (x > 0) {
|
|
return simple(x: x) + simple(x: x)
|
|
} else {
|
|
return simple(x: x) * simple(x: x)
|
|
}
|
|
}
|
|
// CHECK-NOT: "reverse-mode derivative of vjp_inlining.simple(x:)" inlined into "reverse-mode derivative of vjp_inlining.wrapperWithControlFlowOnSimple(x:)"
|
|
|
|
// =============================================================== //
|
|
// VJPs without control-flow are inlined into VJP callers
|
|
// =============================================================== //
|
|
@differentiable(reverse)
|
|
func wrapperOnSimple(x: Float) -> Float {
|
|
return simple(x: x)
|
|
}
|
|
// CHECK-LABEL: decision {{.*}} $s12vjp_inlining6simple1xS2f_tFTJrSpSr
|
|
// CHECK-NEXT: "reverse-mode derivative of vjp_inlining.simple(x:)" inlined into "reverse-mode derivative of vjp_inlining.wrapperOnSimple(x:)"
|