| // RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -disable-objc-interop -emit-ir %s | %FileCheck %s |
| |
| // REQUIRES: CPU=x86_64 |
| |
| // CHECK: [[TYPE:%swift.type]] = type |
| // CHECK: [[C:%T7unowned1CC]] = type <{ [[REF:%swift.refcounted]] }> |
| // CHECK: [[OPAQUE:%swift.opaque]] = type opaque |
| // CHECK: [[A:%T7unowned1AV]] = type <{ %swift.unowned }> |
| |
| import Builtin |
| |
| class C {} |
| sil_vtable C {} |
| |
| typealias AnyObject = Builtin.AnyObject |
| protocol P : class { |
| func explode() |
| } |
| |
| sil @$S7unowned1CCfD : $@convention(method) (C) -> () |
| |
| struct A { |
| unowned var x : C |
| } |
| |
| sil @test_weak_rr_class : $@convention(thin) (@sil_unowned C) -> () { |
| bb0(%0 : $@sil_unowned C): |
| unowned_retain %0 : $@sil_unowned C |
| unowned_release %0 : $@sil_unowned C |
| %3 = tuple () |
| return %3 : $() |
| } |
| // CHECK: define{{( protected)?}} swiftcc void @test_weak_rr_class([[C]]*) {{.*}} { |
| // CHECK: call [[C]]* bitcast ([[REF]]* ([[REF]]*)* @swift_unownedRetain to [[C]]* ([[C]]*)*)([[C]]* returned %0) |
| // CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRelease to void ([[C]]*)*)([[C]]* %0) |
| // CHECK-NEXT: ret void |
| |
| sil @test_weak_rr_proto : $@convention(thin) (@sil_unowned P) -> () { |
| bb0(%0 : $@sil_unowned P): |
| unowned_retain %0 : $@sil_unowned P |
| unowned_release %0 : $@sil_unowned P |
| %3 = tuple () |
| return %3 : $() |
| } |
| // CHECK: define{{( protected)?}} swiftcc void @test_weak_rr_proto(%swift.refcounted*, i8**) {{.*}} { |
| // CHECK: call %swift.refcounted* @swift_unownedRetain(%swift.refcounted* returned %0) |
| // CHECK: call void @swift_unownedRelease(%swift.refcounted* %0) |
| // CHECK-NEXT: ret void |
| |
| // Value witnesses for A: |
| |
| // initializeBufferWithCopyOfBuffer |
| // CHECK: define linkonce_odr hidden [[OPAQUE]]* @"$S7unowned1AVwCP"([[BUFFER:\[24 x i8\]]]* noalias [[DESTBUF:%.*]], [[BUFFER]]* noalias [[SRCBUF:%.*]], [[TYPE]]* |
| // CHECK: [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to [[A]]* |
| // CHECK-NEXT: [[SRC:%.*]] = bitcast [[BUFFER]]* [[SRCBUF]] to [[A]]* |
| // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0 |
| // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0 |
| // CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]* |
| // CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1C]], align 8 |
| // CHECK-NEXT: call [[C]]* bitcast ([[REF]]* ([[REF]]*)* @swift_unownedRetain to [[C]]* ([[C]]*)*)([[C]]* returned [[T2]]) |
| // CHECK-NEXT: [[T0C:%.*]] = bitcast %swift.unowned* [[T0]] to [[C]]* |
| // CHECK-NEXT: store [[C]]* [[T2]], [[C]]** [[T0C]], align 8 |
| // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]* |
| // CHECK-NEXT: ret [[OPAQUE]]* [[T0]] |
| |
| // destroy |
| // CHECK: define linkonce_odr hidden void @"$S7unowned1AVwxx"([[OPAQUE]]* noalias [[ARG:%.*]], [[TYPE]]* |
| // CHECK: [[T0:%.*]] = bitcast [[OPAQUE]]* [[ARG]] to [[A]]* |
| // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i32 0, i32 0 |
| // CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]* |
| // CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1C]], align 8 |
| // CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRelease to void ([[C]]*)*)([[C]]* [[T2]]) |
| // CHECK-NEXT: ret void |
| |
| // initializeWithCopy |
| // CHECK: define linkonce_odr hidden [[OPAQUE]]* @"$S7unowned1AVwcp"([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]* |
| // CHECK: [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]* |
| // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]* |
| // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0 |
| // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0 |
| // CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]* |
| // CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1C]], align 8 |
| // CHECK-NEXT: call [[C]]* bitcast ([[REF]]* ([[REF]]*)* @swift_unownedRetain to [[C]]* ([[C]]*)*)([[C]]* returned [[T2]]) |
| // CHECK-NEXT: [[T0C:%.*]] = bitcast %swift.unowned* [[T0]] to [[C]]* |
| // CHECK-NEXT: store [[C]]* [[T2]], [[C]]** [[T0C]], align 8 |
| // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]* |
| // CHECK-NEXT: ret [[OPAQUE]]* [[T0]] |
| |
| // assignWithCopy |
| // CHECK: define linkonce_odr hidden [[OPAQUE]]* @"$S7unowned1AVwca"([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]* |
| // CHECK: [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]* |
| // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]* |
| // CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0 |
| // CHECK-NEXT: [[SRC_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0 |
| // CHECK-NEXT: [[SRC_X_C:%.*]] = bitcast %swift.unowned* [[SRC_X]] to [[C]]* |
| // CHECK-NEXT: [[NEW:%.*]] = load [[C]]*, [[C]]** [[SRC_X_C]], align 8 |
| // CHECK-NEXT: call [[C]]* bitcast ([[REF]]* ([[REF]]*)* @swift_unownedRetain to [[C]]* ([[C]]*)*)([[C]]* returned [[NEW]]) |
| // CHECK-NEXT: [[DEST_X_C:%.*]] = bitcast %swift.unowned* [[DEST_X]] to [[C]]* |
| // CHECK-NEXT: [[OLD:%.*]] = load [[C]]*, [[C]]** [[DEST_X_C]], align 8 |
| // CHECK-NEXT: store [[C]]* [[NEW]], [[C]]** [[DEST_X_C]], align 8 |
| // CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRelease to void ([[C]]*)*)([[C]]* [[OLD]]) |
| // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]* |
| // CHECK-NEXT: ret [[OPAQUE]]* [[T0]] |
| |
| // assignWithTake |
| // CHECK: define linkonce_odr hidden [[OPAQUE]]* @"$S7unowned1AVwta"([[OPAQUE]]* noalias [[DEST_OPQ:%.*]], [[OPAQUE]]* noalias [[SRC_OPQ:%.*]], [[TYPE]]* |
| // CHECK: [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]* |
| // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]* |
| // CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0 |
| // CHECK-NEXT: [[SRC_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0 |
| // CHECK-NEXT: [[SRC_X_C:%.*]] = bitcast %swift.unowned* [[SRC_X]] to [[C]]* |
| // CHECK-NEXT: [[NEW:%.*]] = load [[C]]*, [[C]]** [[SRC_X_C]], align 8 |
| // CHECK-NEXT: [[DEST_X_C:%.*]] = bitcast %swift.unowned* [[DEST_X]] to [[C]]* |
| // CHECK-NEXT: [[OLD:%.*]] = load [[C]]*, [[C]]** [[DEST_X_C]], align 8 |
| // CHECK-NEXT: store [[C]]* [[NEW]], [[C]]** [[DEST_X_C]], align 8 |
| // CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRelease to void ([[C]]*)*)([[C]]* [[OLD]]) |
| // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]* |
| // CHECK-NEXT: ret [[OPAQUE]]* [[T0]] |