// 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) -> () { bb0(%0 : $*A, %1 : $Optional): %2 = struct_element_addr %0 : $*A, #A.x %3 = load_weak %2 : $*@sil_weak Optional store_weak %1 to %2 : $*@sil_weak Optional release_value %3 : $Optional %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

) -> () { bb0(%0 : $*B, %1 : $Optional

): %2 = struct_element_addr %0 : $*B, #B.x %3 = load_weak %2 : $*@sil_weak Optional

store_weak %1 to %2 : $*@sil_weak Optional

release_value %3 : $Optional

%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

) -> () { bb0(%0 : $Optional

): %1 = alloc_stack $@sil_weak Optional

store_weak %0 to [init] %1 : $*@sil_weak Optional

destroy_addr %1 : $*@sil_weak Optional

dealloc_stack %1 : $*@sil_weak Optional

%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