Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-13530] Forward-mode differentiation: "leaked owned value" verification failure #55967

Closed
dan-zheng opened this issue Sep 9, 2020 · 1 comment
Labels
AutoDiff bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself crash Bug: A crash, i.e., an abnormal termination of software

Comments

@dan-zheng
Copy link
Collaborator

Previous ID SR-13530
Radar None
Original Reporter @dan-zheng
Type Bug
Status Closed
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, AutoDiff, CompilerCrash
Assignee None
Priority Medium

md5: 23392d5b7593a21b7881d22c47fe0196

Issue Description:

Reproducer (occurs when there is a precondition(...) call in the original function, taking and returning a non-trivial Differentiable type):

// Note: non-trivial type, used within resilience boundaries.
struct Tracked<T: Differentiable> {
  class Box {}
  var box = Box()

  var value: T

  init(_ value: T) {
    self.value = value
  }
}
extension Tracked: Equatable where T: Equatable {
  static func ==(lhs: Self, rhs: Self) -> Bool { fatalError() }
}
extension Tracked: AdditiveArithmetic where T: AdditiveArithmetic {
  static func +(lhs: Self, rhs: Self) -> Self { fatalError() }
  static func -(lhs: Self, rhs: Self) -> Self { fatalError() }
  static var zero: Self { fatalError() }
}
extension Tracked: Differentiable where T: Differentiable & AdditiveArithmetic {
  typealias TangentVector = Self
}

@differentiable
func foo(_ x: Tracked<Float>) -> Tracked<Float> {
  precondition(x.value >= 0)
  return x
}

print(differential(at: Tracked(3), in: foo))
$ swiftc -Xfrontend -enable-experimental-forward-mode-differentiation -Xllvm -debug-only=differentiation precond.swift

...

[AD] Activity info for $s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFF at (parameters=(0) results=(0))
bb0:
[ACTIVE] %0 = argument of bb0 : $Tracked<Float>            // users: %23, %3, %1
[NONE]   // function_ref implicit closure #&#8203;1 in foo(_:)
  %2 = function_ref @$s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFFSbyXEfu_ : $@convention(thin) (@guaranteed Tracked<Float>) -> Bool // user: %4
[VARIED]   %3 = copy_value %0 : $Tracked<Float>            // user: %4
[VARIED]   %4 = partial_apply [callee_guaranteed] %2(%3) : $@convention(thin) (@guaranteed Tracked<Float>) -> Bool // users: %22, %5
[VARIED]   %5 = convert_escape_to_noescape [not_guaranteed] %4 : $@callee_guaranteed () -> Bool to $@noescape @callee_guaranteed () -> Bool // user: %20
[NONE]   %6 = string_literal utf8 "precond/precond.swift" // user: %11
[NONE]   %7 = integer_literal $Builtin.Word, 21          // user: %11
[NONE]   %8 = integer_literal $Builtin.Int1, -1          // user: %11
[NONE]   %9 = metatype $@thin StaticString.Type          // user: %11
[NONE]   // function_ref StaticString.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
  %10 = function_ref @$ss12StaticStringV08_builtinB7Literal17utf8CodeUnitCount7isASCIIABBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin StaticString.Type) -> StaticString // user: %11
[NONE]   %11 = apply %10(%6, %7, %8, %9) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin StaticString.Type) -> StaticString // user: %20
[NONE]   %12 = integer_literal $Builtin.IntLiteral, 5    // user: %15
[NONE]   %13 = metatype $@thin UInt.Type                 // user: %15
[NONE]   // function_ref UInt.init(_builtinIntegerLiteral:)
  %14 = function_ref @$sSu22_builtinIntegerLiteralSuBI_tcfC : $@convention(method) (Builtin.IntLiteral, @thin UInt.Type) -> UInt // user: %15
[NONE]   %15 = apply %14(%12, %13) : $@convention(method) (Builtin.IntLiteral, @thin UInt.Type) -> UInt // user: %20
[NONE]   // function_ref default argument 1 of precondition(_:_:file:line:)
  %16 = function_ref @$ss12precondition__4file4lineySbyXK_SSyXKs12StaticStringVSutFfA0_ : $@convention(thin) () -> @owned @callee_guaranteed () -> @owned String // user: %17
[NONE]   %17 = apply %16() : $@convention(thin) () -> @owned @callee_guaranteed () -> @owned String // users: %21, %18
[NONE]   %18 = convert_escape_to_noescape [not_guaranteed] %17 : $@callee_guaranteed () -> @owned String to $@noescape @callee_guaranteed () -> @owned String // user: %20
[NONE]   // function_ref precondition(_:_:file:line:)
  %19 = function_ref @$ss12precondition__4file4lineySbyXK_SSyXKs12StaticStringVSutF : $@convention(thin) (@noescape @callee_guaranteed () -> Bool, @noescape @callee_guaranteed () -> @owned String, StaticString, UInt) -> () // user: %20
[NONE]   %20 = apply %19(%5, %18, %11, %15) : $@convention(thin) (@noescape @callee_guaranteed () -> Bool, @noescape @callee_guaranteed () -> @owned String, StaticString, UInt) -> ()
[ACTIVE]   %23 = copy_value %0 : $Tracked<Float>           // user: %24

...

[AD] Original bb0: To differentiate or not to differentiate?
[ ]   debug_value %0 : $Tracked<Float>, let, name "x", argno 1 // id: %1
[ ]   // function_ref implicit closure #&#8203;1 in foo(_:)
  %2 = function_ref @$s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFFSbyXEfu_ : $@convention(thin) (@guaranteed Tracked<Float>) -> Bool // user: %4
[x]   %3 = copy_value %0 : $Tracked<Float>            // user: %4
[ ]   %4 = partial_apply [callee_guaranteed] %2(%3) : $@convention(thin) (@guaranteed Tracked<Float>) -> Bool // users: %22, %5
[ ]   %5 = convert_escape_to_noescape [not_guaranteed] %4 : $@callee_guaranteed () -> Bool to $@noescape @callee_guaranteed () -> Bool // user: %20
[ ]   %6 = string_literal utf8 "precond/precond.swift" // user: %11
[ ]   %7 = integer_literal $Builtin.Word, 21          // user: %11
[ ]   %8 = integer_literal $Builtin.Int1, -1          // user: %11
[ ]   %9 = metatype $@thin StaticString.Type          // user: %11
[ ]   // function_ref StaticString.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
  %10 = function_ref @$ss12StaticStringV08_builtinB7Literal17utf8CodeUnitCount7isASCIIABBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin StaticString.Type) -> StaticString // user: %11
[ ]   %11 = apply %10(%6, %7, %8, %9) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin StaticString.Type) -> StaticString // user: %20
[ ]   %12 = integer_literal $Builtin.IntLiteral, 5    // user: %15
[ ]   %13 = metatype $@thin UInt.Type                 // user: %15
[ ]   // function_ref UInt.init(_builtinIntegerLiteral:)
  %14 = function_ref @$sSu22_builtinIntegerLiteralSuBI_tcfC : $@convention(method) (Builtin.IntLiteral, @thin UInt.Type) -> UInt // user: %15
[ ]   %15 = apply %14(%12, %13) : $@convention(method) (Builtin.IntLiteral, @thin UInt.Type) -> UInt // user: %20
[ ]   // function_ref default argument 1 of precondition(_:_:file:line:)
  %16 = function_ref @$ss12precondition__4file4lineySbyXK_SSyXKs12StaticStringVSutFfA0_ : $@convention(thin) () -> @owned @callee_guaranteed () -> @owned String // user: %17
[ ]   %17 = apply %16() : $@convention(thin) () -> @owned @callee_guaranteed () -> @owned String // users: %21, %18
[ ]   %18 = convert_escape_to_noescape [not_guaranteed] %17 : $@callee_guaranteed () -> @owned String to $@noescape @callee_guaranteed () -> @owned String // user: %20
[ ]   // function_ref precondition(_:_:file:line:)
  %19 = function_ref @$ss12precondition__4file4lineySbyXK_SSyXKs12StaticStringVSutF : $@convention(thin) (@noescape @callee_guaranteed () -> Bool, @noescape @callee_guaranteed () -> @owned String, StaticString, UInt) -> () // user: %20
[ ]   %20 = apply %19(%5, %18, %11, %15) : $@convention(thin) (@noescape @callee_guaranteed () -> Bool, @noescape @callee_guaranteed () -> @owned String, StaticString, UInt) -> ()
[ ]   destroy_value %17 : $@callee_guaranteed () -> @owned String // id: %21
[ ]   destroy_value %4 : $@callee_guaranteed () -> Bool // id: %22
[x]   %23 = copy_value %0 : $Tracked<Float>           // user: %24
[ ]   return %23 : $Tracked<Float>                    // id: %24

...

[AD] Generated differential for $s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFF:
// AD__$s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFF__differential_src_0_wrt_0
sil hidden [ossa] @AD__$s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFF__differential_src_0_wrt_0 : $@convention(thin) (@guaranteed Tracked<Float>, @owned _AD__$s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFF_bb0__DF__src_0_wrt_0) -> @owned Tracked<Float> {
// %0                                             // users: %4, %3
// %1                                             // user: %2
bb0(%0 : @guaranteed $Tracked<Float>, %1 : $_AD__$s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFF_bb0__DF__src_0_wrt_0):
  destructure_struct %1 : $_AD__$s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFF_bb0__DF__src_0_wrt_0 // id: %2
  %3 = copy_value %0 : $Tracked<Float>
  %4 = copy_value %0 : $Tracked<Float>            // user: %5
  return %4 : $Tracked<Float>                     // id: %5
} // end sil function 'AD__$s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFF__differential_src_0_wrt_0'

...

Begin Error in Function: 'AD__$s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFF__differential_src_0_wrt_0'
Error! Found a leaked owned value that was never consumed.
Value:   %3 = copy_value %0 : $Tracked<Float>

End Error in Function: 'AD__$s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFF__differential_src_0_wrt_0'
Found ownership error?!
triggering standard assertion failure routine
UNREACHABLE executed at /Users/swiftninjas/s4tf/swift/lib/SIL/Verifier/LinearLifetimeCheckerPrivate.h:211!
Stack dump:
0.  Program arguments: /Users/swiftninjas/s4tf/build/Ninja-ReleaseAssert+swift-DebugAssert/swift-macosx-x86_64/bin/swift-frontend -frontend -c -primary-file precond.swift -target x86_64-apple-darwin19.4.0 -enable-objc-interop -sdk /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -color-diagnostics -enable-experimental-forward-mode-differentiation -Xllvm -debug-only=differentiation -target-sdk-version 10.16 -module-name precond -o /var/folders/m_/6f7q8zfs3n9fr0c_4gy8840m00hc_q/T/precond-6b8e78.o
1.  Swift version 5.3-dev (LLVM 14a10d635b229fb, Swift 39c6ee112f95980)
2.  While evaluating request ExecuteSILPipelineRequest(Run pipelines { Mandatory Diagnostic Passes + Enabling Optimization Passes } on SIL for precond.precond)
3.  While running pass #&#8203;29 SILModuleTransform "MandatoryInlining".
4.  While verifying SIL function "@AD__$s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFF__differential_src_0_wrt_0".
 for 'foo(_:)' (at precond.swift:4:1)

SIL for the original function:

// foo(_:)
sil hidden [ossa] @$s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFF : $@convention(thin) (@guaranteed Tracked<Float>) -> @owned Tracked<Float> {
// %0 "x"                                         // users: %23, %3, %1
bb0(%0 : @guaranteed $Tracked<Float>):
  debug_value %0 : $Tracked<Float>, let, name "x", argno 1 // id: %1
  // function_ref implicit closure #&#8203;1 in foo(_:)
  %2 = function_ref @$s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFFSbyXEfu_ : $@convention(thin) (@guaranteed Tracked<Float>) -> Bool // user: %4
  %3 = copy_value %0 : $Tracked<Float>            // user: %4
  %4 = partial_apply [callee_guaranteed] %2(%3) : $@convention(thin) (@guaranteed Tracked<Float>) -> Bool // users: %22, %5
  %5 = convert_escape_to_noescape [not_guaranteed] %4 : $@callee_guaranteed () -> Bool to $@noescape @callee_guaranteed () -> Bool // user: %20
  %6 = string_literal utf8 "precond/precond.swift" // user: %11
  %7 = integer_literal $Builtin.Word, 21          // user: %11
  %8 = integer_literal $Builtin.Int1, -1          // user: %11
  %9 = metatype $@thin StaticString.Type          // user: %11
  // function_ref StaticString.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:)
  %10 = function_ref @$ss12StaticStringV08_builtinB7Literal17utf8CodeUnitCount7isASCIIABBp_BwBi1_tcfC : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin StaticString.Type) -> StaticString // user: %11
  %11 = apply %10(%6, %7, %8, %9) : $@convention(method) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin StaticString.Type) -> StaticString // user: %20
  %12 = integer_literal $Builtin.IntLiteral, 5    // user: %15
  %13 = metatype $@thin UInt.Type                 // user: %15
  // function_ref UInt.init(_builtinIntegerLiteral:)
  %14 = function_ref @$sSu22_builtinIntegerLiteralSuBI_tcfC : $@convention(method) (Builtin.IntLiteral, @thin UInt.Type) -> UInt // user: %15
  %15 = apply %14(%12, %13) : $@convention(method) (Builtin.IntLiteral, @thin UInt.Type) -> UInt // user: %20
  // function_ref default argument 1 of precondition(_:_:file:line:)
  %16 = function_ref @$ss12precondition__4file4lineySbyXK_SSyXKs12StaticStringVSutFfA0_ : $@convention(thin) () -> @owned @callee_guaranteed () -> @owned String // user: %17
  %17 = apply %16() : $@convention(thin) () -> @owned @callee_guaranteed () -> @owned String // users: %21, %18
  %18 = convert_escape_to_noescape [not_guaranteed] %17 : $@callee_guaranteed () -> @owned String to $@noescape @callee_guaranteed () -> @owned String // user: %20
  // function_ref precondition(_:_:file:line:)
  %19 = function_ref @$ss12precondition__4file4lineySbyXK_SSyXKs12StaticStringVSutF : $@convention(thin) (@noescape @callee_guaranteed () -> Bool, @noescape @callee_guaranteed () -> @owned String, StaticString, UInt) -> () // user: %20
  %20 = apply %19(%5, %18, %11, %15) : $@convention(thin) (@noescape @callee_guaranteed () -> Bool, @noescape @callee_guaranteed () -> @owned String, StaticString, UInt) -> ()
  destroy_value %17 : $@callee_guaranteed () -> @owned String // id: %21
  destroy_value %4 : $@callee_guaranteed () -> Bool // id: %22
  %23 = copy_value %0 : $Tracked<Float>           // user: %24
  return %23 : $Tracked<Float>                    // id: %24
} // end sil function '$s7precond3fooy23DifferentiationUnittest7TrackedVySfGAFF'
@dan-zheng
Copy link
Collaborator Author

Fixed in #33898

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@AnthonyLatsis AnthonyLatsis added the crash Bug: A crash, i.e., an abnormal termination of software label Dec 12, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AutoDiff bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself crash Bug: A crash, i.e., an abnormal termination of software
Projects
None yet
Development

No branches or pull requests

2 participants