Skip to content

[SR-12886] SIL memory ownership error for differentiation transform + definite initialization #55333

@dan-zheng

Description

@dan-zheng
Previous ID SR-12886
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 @dan-zheng
Priority Medium

md5: 15cde5e9aa9f3643df01505013ea14b2

relates to:

  • SR-12887 Differentiation transform: debug scope error for VJPEmitter-generated function

Issue Description:

import _Differentiation

enum Enum {
  case a
}

struct Tensor<T>: Differentiable {
  @noDerivative var x: T
  @noDerivative var optional: Int?

  init(_ x: T, _ e: Enum) {
    self.x = x
    switch e {
      case .a: optional = 1
    }
  }

  // Differentiation + definite initialization trigger for this initializer.
  @differentiable
  init(_ x: T, _ other: Self) {
    self = Self(x, Enum.a)
  }
}
$ swiftc crash.swift
SIL memory lifetime failure in @AD__$s5crash6TensorVyACyxGx_ADtcfC__vjp_src_0_wrt_1_l: memory is not initialized, but should
memory location:   %29 = struct_element_addr %5 : $*Tensor<τ_0_0>, #Tensor.x // user: %30
at instruction:   destroy_addr %29 : $*τ_0_0                     // id: %30

in function:
// AD__$s5crash6TensorVyACyxGx_ADtcfC__vjp_src_0_wrt_1_l
sil hidden [ossa] @AD__$s5crash6TensorVyACyxGx_ADtcfC__vjp_src_0_wrt_1_l : $@convention(method) <τ_0_0> (@in τ_0_0, @in Tensor<τ_0_0>, @thin Tensor<τ_0_0>.Type) -> (@out Tensor<τ_0_0>, @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <Tensor<τ_0_0>.TangentVector, Tensor<τ_0_0>.TangentVector>) {
// %0                                             // user: %61
// %1                                             // users: %63, %17, %8
// %2                                             // users: %62, %9
bb0(%0 : $*Tensor<τ_0_0>, %1 : $*τ_0_0, %2 : $*Tensor<τ_0_0>, %3 : $@thin Tensor<τ_0_0>.Type):
  %4 = alloc_stack $Builtin.Int2                  // users: %67, %57, %39, %24, %7
  %5 = alloc_stack $Tensor<τ_0_0>, var, name "self" // users: %65, %64, %61, %46, %29, %23, %12
  %6 = integer_literal $Builtin.Int2, 0           // user: %7
  store %6 to [trivial] %4 : $*Builtin.Int2       // id: %7
  debug_value_addr %1 : $*τ_0_0, let, name "x", argno 1 // id: %8
  debug_value_addr %2 : $*Tensor<τ_0_0>, let, name "other", argno 2 // id: %9
  // function_ref variable initialization expression of Tensor.optional
  %10 = function_ref @$s5crash6TensorV8optionalSiSgvpfi : $@convention(thin) <τ_0_0> () -> Optional<Int> // user: %11
  %11 = apply %10<τ_0_0>() : $@convention(thin) <τ_0_0> () -> Optional<Int> // user: %13
  %12 = struct_element_addr %5 : $*Tensor<τ_0_0>, #Tensor.optional // user: %13
  store %11 to [trivial] %12 : $*Optional<Int>    // id: %13
  %14 = alloc_stack $Tensor<τ_0_0>               // users: %60, %58, %21
  %15 = metatype $@thin Tensor<τ_0_0>.Type       // user: %21
  %16 = alloc_stack $τ_0_0                       // users: %22, %21, %17
  copy_addr %1 to [initialization] %16 : $*τ_0_0 // id: %17
  %18 = metatype $@thin Enum.Type
  %19 = enum $Enum, #Enum.a!enumelt               // user: %21
  // function_ref Tensor.init(_:_:)
  %20 = function_ref @$s5crash6TensorVyACyxGx_AA4EnumOtcfC : $@convention(method) <τ_0_0> (@in τ_0_0, Enum, @thin Tensor<τ_0_0>.Type) -> @out Tensor<τ_0_0> // user: %21
  %21 = apply %20<τ_0_0>(%14, %16, %19, %15) : $@convention(method) <τ_0_0> (@in τ_0_0, Enum, @thin Tensor<τ_0_0>.Type) -> @out Tensor<τ_0_0>
  dealloc_stack %16 : $*τ_0_0                    // id: %22
  %23 = begin_access [modify] [static] %5 : $*Tensor<τ_0_0> // users: %59, %58
  %24 = load [trivial] %4 : $*Builtin.Int2        // user: %25
  %25 = builtin "trunc_Int2_Int1"(%24 : $Builtin.Int2) : $Builtin.Int1 // user: %27
  %26 = struct $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb0__PB__src_0_wrt_1_l<τ_0_0> () // users: %34, %28
  cond_br %25, bb1, bb2                           // id: %27

bb1:                                              // Preds: bb0
  %28 = enum $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb1__Pred__src_0_wrt_1_l<τ_0_0>, #_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb1__Pred__src_0_wrt_1_l.bb0!enumelt, %26 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb0__PB__src_0_wrt_1_l<τ_0_0> // user: %31
  %29 = struct_element_addr %5 : $*Tensor<τ_0_0>, #Tensor.x // user: %30
  destroy_addr %29 : $*τ_0_0                     // id: %30
  %31 = struct $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb1__PB__src_0_wrt_1_l<τ_0_0> (%28 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb1__Pred__src_0_wrt_1_l<τ_0_0>) // user: %32
  %32 = enum $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb3__Pred__src_0_wrt_1_l<τ_0_0>, #_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb3__Pred__src_0_wrt_1_l.bb1!enumelt, %31 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb1__PB__src_0_wrt_1_l<τ_0_0> // user: %33
  br bb3(%32 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb3__Pred__src_0_wrt_1_l<τ_0_0>) // id: %33

bb2:                                              // Preds: bb0
  %34 = enum $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb2__Pred__src_0_wrt_1_l<τ_0_0>, #_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb2__Pred__src_0_wrt_1_l.bb0!enumelt, %26 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb0__PB__src_0_wrt_1_l<τ_0_0> // user: %35
  %35 = struct $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb2__PB__src_0_wrt_1_l<τ_0_0> (%34 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb2__Pred__src_0_wrt_1_l<τ_0_0>) // user: %36
  %36 = enum $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb3__Pred__src_0_wrt_1_l<τ_0_0>, #_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb3__Pred__src_0_wrt_1_l.bb2!enumelt, %35 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb2__PB__src_0_wrt_1_l<τ_0_0> // user: %37
  br bb3(%36 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb3__Pred__src_0_wrt_1_l<τ_0_0>) // id: %37

// %38                                            // user: %43
bb3(%38 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb3__Pred__src_0_wrt_1_l<τ_0_0>): // Preds: bb2 bb1
  %39 = load [trivial] %4 : $*Builtin.Int2        // user: %41
  %40 = integer_literal $Builtin.Int2, 1          // user: %41
  %41 = builtin "lshr_Int2"(%39 : $Builtin.Int2, %40 : $Builtin.Int2) : $Builtin.Int2 // user: %42
  %42 = builtin "trunc_Int2_Int1"(%41 : $Builtin.Int2) : $Builtin.Int1 // user: %44
  %43 = struct $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb3__PB__src_0_wrt_1_l<τ_0_0> (%38 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb3__Pred__src_0_wrt_1_l<τ_0_0>) // users: %51, %45
  cond_br %42, bb4, bb5                           // id: %44

bb4:                                              // Preds: bb3
  %45 = enum $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb4__Pred__src_0_wrt_1_l<τ_0_0>, #_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb4__Pred__src_0_wrt_1_l.bb3!enumelt, %43 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb3__PB__src_0_wrt_1_l<τ_0_0> // user: %48
  %46 = struct_element_addr %5 : $*Tensor<τ_0_0>, #Tensor.optional // user: %47
  destroy_addr %46 : $*Optional<Int>              // id: %47
  %48 = struct $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb4__PB__src_0_wrt_1_l<τ_0_0> (%45 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb4__Pred__src_0_wrt_1_l<τ_0_0>) // user: %49
  %49 = enum $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb6__Pred__src_0_wrt_1_l<τ_0_0>, #_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb6__Pred__src_0_wrt_1_l.bb4!enumelt, %48 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb4__PB__src_0_wrt_1_l<τ_0_0> // user: %50
  br bb6(%49 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb6__Pred__src_0_wrt_1_l<τ_0_0>) // id: %50

bb5:                                              // Preds: bb3
  %51 = enum $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb5__Pred__src_0_wrt_1_l<τ_0_0>, #_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb5__Pred__src_0_wrt_1_l.bb3!enumelt, %43 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb3__PB__src_0_wrt_1_l<τ_0_0> // user: %52
  %52 = struct $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb5__PB__src_0_wrt_1_l<τ_0_0> (%51 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb5__Pred__src_0_wrt_1_l<τ_0_0>) // user: %53
  %53 = enum $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb6__Pred__src_0_wrt_1_l<τ_0_0>, #_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb6__Pred__src_0_wrt_1_l.bb5!enumelt, %52 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb5__PB__src_0_wrt_1_l<τ_0_0> // user: %54
  br bb6(%53 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb6__Pred__src_0_wrt_1_l<τ_0_0>) // id: %54

// %55                                            // user: %68
bb6(%55 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb6__Pred__src_0_wrt_1_l<τ_0_0>): // Preds: bb5 bb4
  %56 = integer_literal $Builtin.Int2, -1         // user: %57
  store %56 to [trivial] %4 : $*Builtin.Int2      // id: %57
  copy_addr [take] %14 to [initialization] %23 : $*Tensor<τ_0_0> // id: %58
  end_access %23 : $*Tensor<τ_0_0>               // id: %59
  dealloc_stack %14 : $*Tensor<τ_0_0>            // id: %60
  copy_addr %5 to [initialization] %0 : $*Tensor<τ_0_0> // id: %61
  destroy_addr %2 : $*Tensor<τ_0_0>              // id: %62
  destroy_addr %1 : $*τ_0_0                      // id: %63
  destroy_addr %5 : $*Tensor<τ_0_0>              // id: %64
  dealloc_stack %5 : $*Tensor<τ_0_0>             // id: %65
  %66 = tuple ()                                  // user: %69
  dealloc_stack %4 : $*Builtin.Int2               // id: %67
  %68 = struct $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb6__PB__src_0_wrt_1_l<τ_0_0> (%55 : $_AD__$s5crash6TensorVyACyxGx_ADtcfC_bb6__Pred__src_0_wrt_1_l<τ_0_0>) // user: %71
  destructure_tuple %66 : $()                     // id: %69
  // function_ref AD__$s5crash6TensorVyACyxGx_ADtcfC__pullback_src_0_wrt_1_l
  %70 = function_ref @AD__$s5crash6TensorVyACyxGx_ADtcfC__pullback_src_0_wrt_1_l : $@convention(method) <τ_0_0> (@in_guaranteed Tensor<τ_0_0>.TangentVector, @owned _AD__$s5crash6TensorVyACyxGx_ADtcfC_bb6__PB__src_0_wrt_1_l<τ_0_0>) -> @out Tensor<τ_0_0>.TangentVector // user: %71
  %71 = partial_apply [callee_guaranteed] %70<τ_0_0>(%68) : $@convention(method) <τ_0_0> (@in_guaranteed Tensor<τ_0_0>.TangentVector, @owned _AD__$s5crash6TensorVyACyxGx_ADtcfC_bb6__PB__src_0_wrt_1_l<τ_0_0>) -> @out Tensor<τ_0_0>.TangentVector // user: %72
  %72 = convert_function %71 : $@callee_guaranteed (@in_guaranteed Tensor<τ_0_0>.TangentVector) -> @out Tensor<τ_0_0>.TangentVector to $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <Tensor<τ_0_0>.TangentVector, Tensor<τ_0_0>.TangentVector> // user: %73
  return %72 : $@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <Tensor<τ_0_0>.TangentVector, Tensor<τ_0_0>.TangentVector> // id: %73
} // end sil function 'AD__$s5crash6TensorVyACyxGx_ADtcfC__vjp_src_0_wrt_1_l'

Metadata

Metadata

Assignees

Labels

AutoDiffbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselfcrashBug: A crash, i.e., an abnormal termination of software

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions