1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
// RUN: %target-swift-frontend -enable-objc-interop -disable-type-layout -emit-ir %s | %FileCheck %s
// RUN: %target-swift-frontend -O -S %s | %FileCheck %s --check-prefix=TAILCALL
// REQUIRES: CPU=x86_64
// CHECK-DAG: [[TYPE:%swift.type]] = type
// CHECK-DAG: [[OPAQUE:%swift.opaque]] = type opaque
sil_stage canonical
import Swift
public class C {}
sil_vtable C {}
sil @$s4weak1CCfD : $@convention(method) (C) -> ()
protocol P : class {
func explode()
}
public struct A {
weak var x : C?
}
// size 8
// stride 8
// flags 0x130007 == 1245191 (non-POD, non-inline, non-bitwise-takable)
// CHECK: @"$s4weak1AVWV" = {{.*}} i64 8, i64 8, i32 1245191,
sil @test_weak_load_store : $@convention(thin) (@inout A, Optional<C>) -> () {
bb0(%0 : $*A, %1 : $Optional<C>):
%2 = struct_element_addr %0 : $*A, #A.x
%3 = load_weak %2 : $*@sil_weak Optional<C>
store_weak %1 to %2 : $*@sil_weak Optional<C>
release_value %3 : $Optional<C>
%4 = tuple ()
return %4 : $()
}
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_weak_load_store(ptr dereferenceable({{.*}}) %0, i64 %1) {{.*}} {
// CHECK: [[X:%.*]] = getelementptr inbounds [[A:%T4weak1AV]], ptr %0, i32 0, i32 0
// CHECK-NEXT: [[T0:%.*]] = call ptr @swift_weakLoadStrong(ptr [[X]])
// CHECK-NEXT: %3 = ptrtoint ptr %2 to i64
// CHECK-NEXT: %4 = inttoptr
// CHECK-NEXT: call ptr @swift_weakAssign(ptr returned [[X]], ptr %4)
// CHECK-NEXT: %6 = inttoptr i64 %3 to ptr
// CHECK-NEXT: call void @swift_release(ptr %6)
// CHECK-NEXT: ret void
struct B {
weak var x : P?
}
sil @test_weak_load_store_proto : $@convention(thin) (@inout B, Optional<P>) -> () {
bb0(%0 : $*B, %1 : $Optional<P>):
%2 = struct_element_addr %0 : $*B, #B.x
%3 = load_weak %2 : $*@sil_weak Optional<P>
store_weak %1 to %2 : $*@sil_weak Optional<P>
release_value %3 : $Optional<P>
%4 = tuple ()
return %4 : $()
}
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_weak_load_store_proto(ptr dereferenceable({{.*}}) %0, i64 %1, i64 %2)
// CHECK: [[X:%.*]] = getelementptr inbounds [[B:%T4weak1BV]], ptr %0, i32 0, i32 0
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { [[WEAK:%swift.weak]], ptr }, ptr [[X]], i32 0, i32 0
// CHECK-NEXT: [[T1:%.*]] = call ptr @swift_unknownObjectWeakLoadStrong(ptr [[T0]])
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { [[WEAK]], ptr }, ptr [[X]], i32 0, i32 1
// CHECK-NEXT: [[W:%.*]] = load ptr, ptr [[T0]], align 8
// CHECK: [[TMPOBJ:%.*]] = inttoptr {{.*}} to ptr
// CHECK: [[TMPTAB:%.*]] = inttoptr {{.*}} to ptr
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { [[WEAK]], ptr }, ptr [[X]], i32 0, i32 1
// CHECK-NEXT: store ptr [[TMPTAB]], ptr [[T0]], align 8
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { [[WEAK]], ptr }, ptr [[X]], i32 0, i32 0
// CHECK-NEXT: call ptr @swift_unknownObjectWeakAssign(ptr returned [[T0]], ptr [[TMPOBJ]])
// CHECK: call void @swift_unknownObjectRelease
sil @test_weak_alloc_stack : $@convention(thin) (Optional<P>) -> () {
bb0(%0 : $Optional<P>):
%1 = alloc_stack $@sil_weak Optional<P>
store_weak %0 to [init] %1 : $*@sil_weak Optional<P>
destroy_addr %1 : $*@sil_weak Optional<P>
dealloc_stack %1 : $*@sil_weak Optional<P>
%4 = tuple ()
return %4 : $()
}
// CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_weak_alloc_stack(i64 %0, i64 %1)
// CHECK: [[X:%.*]] = alloca { [[WEAK]], ptr }, align 8
// CHECK: [[TMPOBJ:%.*]] = inttoptr {{.*}} to ptr
// CHECK: [[TMPTAB:%.*]] = inttoptr {{.*}} to ptr
// CHECK: [[T0:%.*]] = getelementptr inbounds { [[WEAK]], ptr }, ptr [[X]], i32 0, i32 1
// CHECK-NEXT: store ptr [[TMPTAB:%.*]], ptr [[T0]], align 8
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { [[WEAK]], ptr }, ptr [[X]], i32 0, i32 0
// CHECK-NEXT: call ptr @swift_unknownObjectWeakInit(ptr returned [[T0]], ptr [[TMPOBJ:%.*]])
// CHECK-NEXT: call ptr @"$s4weak1P_pSgXwWOh"(ptr [[X]])
// CHECK-NEXT: llvm.lifetime.end
// CHECK-NEXT: ret void
// Value witnesses for A:
// initializeBufferWithCopyOfBuffer
// CHECK: define internal ptr @"$s4weak1AVwCP"(ptr noalias [[DESTBUF:%.*]], ptr noalias [[SRCBUF:%.*]], ptr
// CHECK: [[REF:%.*]] = load ptr, ptr [[SRCBUF]]
// CHECK: call ptr @swift_retain(ptr returned [[REF]])
// CHECK: store ptr [[REF]], ptr [[DESTBUF]]
// CHECK: [[REF:%.*]] = load ptr, ptr [[DESTBUF]]
// CHECK: [[PTR2:%.*]] = getelementptr inbounds i8, ptr [[REF]], {{(i64|i32)}} {{(16|8)}}
// CHECK: ret ptr [[PTR2]]
// destroy
// CHECK: define internal void @"$s4weak1AVwxx"(ptr noalias [[ARG:%.*]], ptr
// CHECK: [[T1:%.*]] = getelementptr inbounds [[A]], ptr [[ARG]], i32 0, i32 0
// CHECK-NEXT: call void @swift_weakDestroy(ptr [[T1]])
// CHECK-NEXT: ret void
// TAILCALL: {{_?}}$s4weak1AVwxx:
// TAILCALL: jmp{{q?}} {{(\*__imp_)?_?}}swift_weakDestroy
// initializeWithCopy
// CHECK: define internal ptr @"$s4weak1AVwcp"(ptr noalias [[DEST_OPQ:%.*]], ptr noalias [[SRC_OPQ:%.*]], ptr
// CHECK: [[T0:%.*]] = getelementptr inbounds [[A]], ptr [[DEST_OPQ]], i32 0, i32 0
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], ptr [[SRC_OPQ]], i32 0, i32 0
// CHECK-NEXT: call ptr @swift_weakCopyInit(ptr returned [[T0]], ptr [[T1]])
// CHECK-NEXT: ret ptr [[DEST_OPQ]]
// TAILCALL: {{_?}}$s4weak1AVwcp:
// TAILCALL: jmp{{q?}} {{(\*__imp_)?_?}}swift_weakCopyInit
// assignWithCopy
// CHECK: define internal ptr @"$s4weak1AVwca"(ptr [[DEST_OPQ:%.*]], ptr [[SRC_OPQ:%.*]], ptr
// CHECK: [[DEST_X:%.*]] = getelementptr inbounds [[A]], ptr [[DEST_OPQ]], i32 0, i32 0
// CHECK-NEXT: [[SRC_X:%.*]] = getelementptr inbounds [[A]], ptr [[SRC_OPQ]], i32 0, i32 0
// CHECK-NEXT: call ptr @swift_weakCopyAssign(ptr returned [[DEST_X]], ptr [[SRC_X]])
// CHECK-NEXT: ret ptr [[DEST_OPQ]]
// TAILCALL: {{_?}}$s4weak1AVwca:
// TAILCALL: jmp{{q?}} {{(\*__imp_)?_?}}swift_weakCopyAssign
// assignWithTake
// CHECK: define internal ptr @"$s4weak1AVwta"(ptr noalias [[DEST_OPQ:%.*]], ptr noalias [[SRC_OPQ:%.*]], ptr
// CHECK: [[DEST_X:%.*]] = getelementptr inbounds [[A]], ptr [[DEST_OPQ]], i32 0, i32 0
// CHECK-NEXT: [[SRC_X:%.*]] = getelementptr inbounds [[A]], ptr [[SRC_OPQ]], i32 0, i32 0
// CHECK-NEXT: call ptr @swift_weakTakeAssign(ptr returned [[DEST_X]], ptr [[SRC_X]])
// CHECK-NEXT: ret ptr [[DEST_OPQ]]
// TAILCALL: {{_?}}$s4weak1AVwtk:
// TAILCALL: jmp{{q?}} {{(\*__imp_)?_?}}swift_weakTakeInit
// TAILCALL: {{_?}}$s4weak1AVwta:
// TAILCALL: jmp{{q?}} {{(\*__imp_)?_?}}swift_weakTakeAssign
|