// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -rc-id-dumper %s -o /dev/null | %FileCheck %s import Builtin /////////////////////// // NonTest Utilities // /////////////////////// typealias AnyObject = Builtin.AnyObject protocol FakeAnyObject : class {} class C : FakeAnyObject { init() } class D : C { override init() } class E { init() } sil @foo : $@convention(thin) (Builtin.Word) -> () struct S1 { var f1 : Builtin.Word var f2 : Builtin.NativeObject var f3 : Builtin.NativeObject } struct S2 { var f1 : Builtin.Word var f2 : S1 var f3 : Builtin.Word } struct S3 { var f1 : Builtin.Word var f2 : Builtin.Word var f3 : Builtin.NativeObject } struct S4 { var f1 : S3 var f2 : Builtin.Word var f5 : Builtin.Word } enum E1 { case Case1 case Case2(S1) case Case3(Builtin.Word) } /////////// // Tests // /////////// // Make sure that we see all the way through the chain of casts that %9 has an RCIdentity of %0 and that %12 is really the partial apply. // CHECK-LABEL: @test_rcid_preserving_casts@ // CHECK: RESULT #9: 9 = 0 // CHECK: RESULT #12: 12 = 11 sil @test_rcid_preserving_casts : $@convention(thin) (Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject): %1 = unconditional_checked_cast %0 : $Builtin.NativeObject to $D %2 = upcast %1 : $D to $C %3 = unchecked_ref_cast %2 : $C to $E %4 = integer_literal $Builtin.Word, 0 %5 = ref_to_bridge_object %3 : $E, %4 : $Builtin.Word %6 = bridge_object_to_ref %5 : $Builtin.BridgeObject to $C %7 = init_existential_ref %6 : $C : $C, $FakeAnyObject %8 = open_existential_ref %7 : $FakeAnyObject to $@opened("A2E21C52-6089-11E4-9866-3C0754723233") FakeAnyObject %9 = unchecked_ref_cast %8 : $@opened("A2E21C52-6089-11E4-9866-3C0754723233") FakeAnyObject to $Builtin.NativeObject %10 = function_ref @foo : $@convention(thin) (Builtin.Word) -> () %11 = partial_apply %10(%4) : $@convention(thin) (Builtin.Word) -> () %12 = convert_function %11 : $@callee_owned @convention(thick) () -> () to $@callee_owned @convention(thick) () -> () return undef : $() } // Make sure that we look through structs with only one reference counted fields // and that we do not look through structs without that property. // // CHECK-LABEL: @test_single_refcount_field_structs@ // CHECK: RESULT #2: 2 = 0 // CHECK: RESULT #3: 3 = 0 // CHECK: RESULT #4: 4 = 4 // CHECK: RESULT #5: 5 = 4 sil @test_single_refcount_field_structs : $@convention(thin) (Builtin.NativeObject, Builtin.Word) -> () { bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.Word): %2 = struct $S3(%1 : $Builtin.Word, %1 : $Builtin.Word, %0 : $Builtin.NativeObject) %3 = struct $S4(%2 : $S3, %1 : $Builtin.Word, %1 : $Builtin.Word) %4 = struct $S1(%1 : $Builtin.Word, %0 : $Builtin.NativeObject, %0 : $Builtin.NativeObject) %5 = struct $S2(%1 : $Builtin.Word, %4 : $S1, %1 : $Builtin.Word) return undef : $() } // CHECK-LABEL: @test_single_refcount_field_tuples@ // CHECK: RESULT #2: 2 = 0 // CHECK: RESULT #3: 3 = 0 // CHECK: RESULT #4: 4 = 4 // CHECK: RESULT #5: 5 = 4 sil @test_single_refcount_field_tuples : $@convention(thin) (Builtin.NativeObject, Builtin.Word) -> () { bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.Word): %2 = tuple(%1 : $Builtin.Word, %1 : $Builtin.Word, %0 : $Builtin.NativeObject) %3 = tuple(%2 : $(Builtin.Word, Builtin.Word, Builtin.NativeObject), %1 : $Builtin.Word, %1 : $Builtin.Word) %4 = tuple(%1 : $Builtin.Word, %0 : $Builtin.NativeObject, %0 : $Builtin.NativeObject) %5 = tuple(%1 : $Builtin.Word, %4 : $(Builtin.Word, Builtin.NativeObject, Builtin.NativeObject), %1 : $Builtin.Word) return undef : $() } // All of the SSA values in the given function besides %6 can be resolved to // (%0, %1). Because %6 has multiple SSA values and there is nothing tricky we // can do here, just bail. // // CHECK-LABEL: @test_single_pred_rc_id@ // CHECK: RESULT #0: 0 = 0 // CHECK: RESULT #1: 1 = 1 // CHECK: RESULT #2: 2 = 0 // CHECK: RESULT #3: 3 = 1 // CHECK: RESULT #4: 4 = 1 // CHECK: RESULT #5: 5 = 0 // CHECK: RESULT #6: 6 = 6 sil @test_single_pred_rc_id : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): br bb1(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject) bb1(%2 : $Builtin.NativeObject, %3 : $Builtin.NativeObject): cond_br undef, bb2(%3 : $Builtin.NativeObject), bb3(%2 : $Builtin.NativeObject) bb2(%4 : $Builtin.NativeObject): br bb4(%4 : $Builtin.NativeObject) bb3(%5 : $Builtin.NativeObject): br bb4(%5 : $Builtin.NativeObject) bb4(%6 : $Builtin.NativeObject): cond_br undef, bb4(%6 : $Builtin.NativeObject), bb5 bb5: return undef : $() } // All of the SSA values in the given function can be resolved to %0. // // CHECK-LABEL: @test_multiple_pred_same_rcid@ // CHECK: RESULT #0: 0 = 0 // CHECK: RESULT #1: 1 = 0 // CHECK: RESULT #2: 2 = 0 // CHECK: RESULT #3: 3 = 0 // CHECK: RESULT #4: 4 = 0 // CHECK: RESULT #5: 5 = 0 sil @test_multiple_pred_same_rcid : $@convention(thin) (Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject): br bb1(%0 : $Builtin.NativeObject, %0 : $Builtin.NativeObject) bb1(%2 : $Builtin.NativeObject, %3 : $Builtin.NativeObject): cond_br undef, bb2(%3 : $Builtin.NativeObject), bb3(%2 : $Builtin.NativeObject) bb2(%4 : $Builtin.NativeObject): br bb4(%4 : $Builtin.NativeObject) bb3(%5 : $Builtin.NativeObject): br bb4(%5 : $Builtin.NativeObject) bb4(%6 : $Builtin.NativeObject): br bb5 bb5: return undef : $() }