mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This attribute was introduced in 7eca38ce76d5d1915f4ab7e665964062c0b37697 (llvm-project). Match it using a wildcard regex, since it is not relevant to these tests. This is intended to reduce future conflicts with rebranch.
149 lines
6.4 KiB
Plaintext
149 lines
6.4 KiB
Plaintext
// 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
|