| // 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> |
| } |
| } |