blob: 89d304d3c21698872628d0f0bef11635b8d9f9ac [file] [log] [blame]
// RUN: %target-swift-frontend -emit-sil %s | %FileCheck %s
class OtherClass {}
class FirstClass {
var x: OtherClass
// CHECK-LABEL: sil hidden @$s24definite_init_root_class10FirstClassC1nACSgs5Int32V_tcfc : $@convention(method) (Int32, @owned FirstClass) -> @owned Optional<FirstClass>
init?(n: Int32) {
// CHECK: [[CONTROL:%.*]] = alloc_stack $Builtin.Int1
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0
// CHECK: store [[ZERO]] to [[CONTROL]] : $*Builtin.Int1
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int32, 0
// CHECK: [[N:%.*]] = struct_extract %0 : $Int32, #Int32._value
// CHECK: [[CMP:%.*]] = builtin "cmp_eq_Int32"([[N]] : $Builtin.Int32, [[ZERO]] : $Builtin.Int32) : $Builtin.Int1
// CHECK: cond_br [[CMP]], bb1, bb2
if n == 0 {
return nil
}
// CHECK: bb1:
// CHECK: br bb5
// CHECK: bb2:
// CHECK: [[METATYPE:%.*]] = metatype $@thick OtherClass.Type
// CHECK: [[INIT:%.*]] = function_ref @$s24definite_init_root_class10OtherClassCACycfC : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
// CHECK: [[OTHER:%.*]] = apply [[INIT]]([[METATYPE]]) : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
// CHECK: [[X_ADDR:%.*]] = ref_element_addr %1 : $FirstClass, #FirstClass.x
// CHECK: [[X_ACCESS:%.*]] = begin_access [modify] [dynamic] %15 : $*OtherClass
// CHECK: [[ONE:%.*]] = integer_literal $Builtin.Int1, -1
// CHECK: store [[ONE]] to [[CONTROL]] : $*Builtin.Int1
// CHECK: store [[OTHER]] to [[X_ACCESS]] : $*OtherClass
// CHECK: end_access [[X_ACCESS]] : $*OtherClass
x = OtherClass()
// CHECK: [[ONE:%.*]] = integer_literal $Builtin.Int32, 1
// CHECK: [[N:%.*]] = struct_extract %0 : $Int32, #Int32._value
// CHECK: [[CMP:%.*]] = builtin "cmp_eq_Int32"([[N]] : $Builtin.Int32, [[ONE]] : $Builtin.Int32) : $Builtin.Int1
// CHECK: cond_br [[CMP]], bb3, bb4
if n == 1 {
return nil
}
// CHECK: bb3:
// CHECK: br bb5
// CHECK: bb4:
// CHECK: [[RESULT:%.*]] = enum $Optional<FirstClass>, #Optional.some!enumelt, %1 : $FirstClass
// CHECK: br bb12([[RESULT]] : $Optional<FirstClass>)
// CHECK: bb5:
// CHECK: [[BIT:%.*]] = load [[CONTROL]] : $*Builtin.Int1
// CHECK: cond_br [[BIT]], bb6, bb7
// CHECK: bb6:
// CHECK: strong_release %1 : $FirstClass
// CHECK: br bb11
// CHECK: bb7:
// CHECK: [[BIT:%.*]] = load [[CONTROL]] : $*Builtin.Int1
// CHECK: cond_br [[BIT]], bb8, bb9
// CHECK: bb8:
// CHECK: [[X_ADDR:%.*]] = ref_element_addr %1 : $FirstClass, #FirstClass.x
// CHECK: [[X_ACCESS:%.*]] = begin_access [deinit] [static] [[X_ADDR]] : $*OtherClass
// CHECK: destroy_addr [[X_ACCESS]] : $*OtherClass
// CHECK: end_access [[X_ACCESS]] : $*OtherClass
// CHECK: br bb10
// CHECK: bb9:
// CHECK: br bb10
// CHECK: [[METATYPE:%.*]] = metatype $@thick FirstClass.Type
// CHECK: dealloc_partial_ref %1 : $FirstClass, [[METATYPE]] : $@thick FirstClass.Type
// CHECK: br bb11
// CHECK: bb11:
// CHECK: [[NIL:%.*]] = enum $Optional<FirstClass>, #Optional.none!enumelt
// CHECK: br bb12([[NIL]] : $Optional<FirstClass>)
// CHECK: bb12([[RESULT:%.*]] : $Optional<FirstClass>):
// CHECK: dealloc_stack [[CONTROL]] : $*Builtin.Int1
// CHECK: return [[RESULT]] : $Optional<FirstClass>
}
}
class SecondClass {
var x: OtherClass
var y: OtherClass
// CHECK-LABEL: sil hidden @$s24definite_init_root_class11SecondClassC1nACSgs5Int32V_tcfc : $@convention(method) (Int32, @owned SecondClass) -> @owned Optional<SecondClass> {
init?(n: Int32) {
// CHECK: [[CONTROL:%.*]] = alloc_stack $Builtin.Int2
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0
// CHECK: store [[ZERO]] to [[CONTROL]] : $*Builtin.Int2
// CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int32, 0
// CHECK: [[N:%.*]] = struct_extract %0 : $Int32, #Int32._value
// CHECK: [[CMP:%.*]] = builtin "cmp_eq_Int32"([[N]] : $Builtin.Int32, [[ZERO]] : $Builtin.Int32) : $Builtin.Int1
// CHECK: cond_br [[CMP]], bb1, bb2
if n == 0 {
return nil
}
// CHECK: bb1:
// CHECK: br bb7
// CHECK: bb2:
// CHECK: [[METATYPE:%.*]] = metatype $@thick OtherClass.Type
// CHECK: [[INIT:%.*]] = function_ref @$s24definite_init_root_class10OtherClassCACycfC : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
// CHECK: [[OTHER:%.*]] = apply [[INIT]]([[METATYPE]]) : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
// CHECK: [[X_ADDR:%.*]] = ref_element_addr %1 : $SecondClass, #SecondClass.x
// CHECK: [[X_ACCESS:%.*]] = begin_access [modify] [dynamic] [[X_ADDR]] : $*OtherClass
// CHECK: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
// CHECK: store [[ONE]] to [[CONTROL]] : $*Builtin.Int2
// CHECK: store [[OTHER]] to [[X_ACCESS]] : $*OtherClass
// CHECK: end_access [[X_ACCESS]] : $*OtherClass
x = OtherClass()
// CHECK: [[ONE:%.*]] = integer_literal $Builtin.Int32, 1
// CHECK: [[N:%.*]] = struct_extract %0 : $Int32, #Int32._value
// CHECK: [[CMP:%.*]] = builtin "cmp_eq_Int32"([[N]] : $Builtin.Int32, [[ONE]] : $Builtin.Int32) : $Builtin.Int1
// CHECK: cond_br [[CMP]], bb3, bb4
if n == 1 {
return nil
}
// CHECK: bb3:
// CHECK: br bb7
// CHECK: bb4:
// CHECK: [[METATYPE:%.*]] = metatype $@thick OtherClass.Type
// CHECK: [[INIT:%.*]] = function_ref @$s24definite_init_root_class10OtherClassCACycfC : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
// CHECK: [[OTHER:%.*]] = apply [[INIT]]([[METATYPE]]) : $@convention(method) (@thick OtherClass.Type) -> @owned OtherClass
// CHECK: [[Y_ADDR:%.*]] = ref_element_addr %1 : $SecondClass, #SecondClass.y
// CHECK: [[Y_ACCESS:%.*]] = begin_access [modify] [dynamic] [[Y_ADDR]] : $*OtherClass
// CHECK: [[THREE:%.*]] = integer_literal $Builtin.Int2, -1
// CHECK: store [[THREE]] to [[CONTROL]] : $*Builtin.Int2
// CHECK: store [[OTHER]] to [[Y_ACCESS]] : $*OtherClass
// CHECK: end_access [[Y_ACCESS]] : $*OtherClass
y = OtherClass()
// CHECK: [[TWO:%.*]] = integer_literal $Builtin.Int32, 2
// CHECK: [[N:%.*]] = struct_extract %0 : $Int32, #Int32._value
// CHECK: [[CMP:%.*]] = builtin "cmp_eq_Int32"([[N]] : $Builtin.Int32, [[TWO]] : $Builtin.Int32) : $Builtin.Int1
// CHECK: cond_br [[CMP]], bb5, bb6
if n == 2 {
return nil
}
// CHECK: bb5:
// CHECK: br bb7
// CHECK: bb6:
// CHECK: [[RESULT:%.*]] = enum $Optional<SecondClass>, #Optional.some!enumelt, %1 : $SecondClass
// CHECK: br bb17([[RESULT]] : $Optional<SecondClass>)
// CHECK: bb7:
// CHECK: [[BITS:%.*]] = load [[CONTROL]] : $*Builtin.Int2
// CHECK: [[THREE:%.*]] = integer_literal $Builtin.Int2, -1
// CHECK: [[BIT:%.*]] = builtin "cmp_eq_Int2"([[BITS]] : $Builtin.Int2, [[THREE]] : $Builtin.Int2) : $Builtin.Int1
// CHECK: cond_br [[BIT]], bb8, bb9
// CHECK: bb8:
// CHECK: strong_release %1 : $SecondClass
// CHECK: br bb16
// CHECK: bb9:
// CHECK: [[BITS:%.*]] = load [[CONTROL]] : $*Builtin.Int2
// CHECK: [[BIT:%.*]] = builtin "trunc_Int2_Int1"([[BITS]] : $Builtin.Int2) : $Builtin.Int1
// CHECK: cond_br [[BIT]], bb10, bb11
// CHECK: bb10:
// CHECK: [[X_ADDR:%.*]] = ref_element_addr %1 : $SecondClass, #SecondClass.x
// CHECK: [[X_ACCESS:%.*]] = begin_access [deinit] [static] [[X_ADDR]] : $*OtherClass
// CHECK: destroy_addr [[X_ACCESS]] : $*OtherClass
// CHECK: end_access [[X_ACCESS]] : $*OtherClass
// CHECK: br bb12
// CHECK: bb11:
// CHECK: br bb12
// CHECK: bb12:
// CHECK: [[BITS:%.*]] = load [[CONTROL]] : $*Builtin.Int2
// CHECK: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1
// CHECK: [[TMP:%.*]] = builtin "lshr_Int2"([[BITS]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2) : $Builtin.Int2
// CHECK: [[BIT:%.*]] = builtin "trunc_Int2_Int1"([[TMP]] : $Builtin.Int2) : $Builtin.Int1
// CHECK: cond_br [[BIT]], bb13, bb14
// CHECK: bb13:
// CHECK: [[Y_ADDR:%.*]] = ref_element_addr %1 : $SecondClass, #SecondClass.y
// CHECK: [[Y_ACCESS:%.*]] = begin_access [deinit] [static] [[Y_ADDR]] : $*OtherClass
// CHECK: destroy_addr [[Y_ACCESS]] : $*OtherClass
// CHECK: end_access [[Y_ACCESS]] : $*OtherClass
// CHECK: br bb15
// CHECK: bb14:
// CHECK: br bb15
// CHECK: bb15:
// CHECK: [[METATYPE:%.*]] = metatype $@thick SecondClass.Type
// CHECK: dealloc_partial_ref %1 : $SecondClass, [[METATYPE]] : $@thick SecondClass.Type
// CHECK: br bb16
// CHECK: bb16:
// CHECK: [[NIL:%.*]] = enum $Optional<SecondClass>, #Optional.none!enumelt
// CHECK: br bb17([[NIL]] : $Optional<SecondClass>)
// CHECK: bb17([[RESULT:%.*]] : $Optional<SecondClass>):
// CHECK: dealloc_stack [[CONTROL]] : $*Builtin.Int2
// CHECK: return [[RESULT]] : $Optional<SecondClass>
}
}