mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
161 lines
6.3 KiB
Plaintext
161 lines
6.3 KiB
Plaintext
// RUN: %target-swift-frontend -disable-type-layout %s -emit-ir | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime --check-prefix=CHECK-%target-runtime-simulator-%target-is-simulator
|
|
|
|
// REQUIRES: CPU=x86_64
|
|
|
|
import Builtin
|
|
|
|
// Enums consisting of a retainable pointer and a single empty case use nullable
|
|
// pointer value semantics.
|
|
enum NullableRefcounted {
|
|
case Ref(Builtin.NativeObject)
|
|
case None
|
|
}
|
|
|
|
// CHECK-LABEL: define internal void @"$s34enum_value_semantics_special_cases18NullableRefcountedOwxx"(ptr noalias %object, ptr %NullableRefcounted) {{.*}} {
|
|
// CHECK: entry:
|
|
// CHECK: %0 = load ptr, ptr %object, align 8
|
|
// CHECK: call void @swift_release(ptr %0)
|
|
// CHECK: ret void
|
|
// CHECK: }
|
|
|
|
// CHECK-LABEL: define internal ptr @"$s34enum_value_semantics_special_cases18NullableRefcountedOwcp"(ptr noalias %dest, ptr noalias %src, ptr %NullableRefcounted) {{.*}} {
|
|
// CHECK: entry:
|
|
// CHECK: %0 = load ptr, ptr %src, align 8
|
|
// CHECK: %1 = call ptr @swift_retain(ptr returned %0)
|
|
// CHECK: store ptr %0, ptr %dest, align 8
|
|
// CHECK: ret ptr %dest
|
|
// CHECK: }
|
|
|
|
// CHECK-LABEL: define internal ptr @"$s34enum_value_semantics_special_cases18NullableRefcountedOwca"(ptr %dest, ptr %src, ptr %NullableRefcounted) {{.*}} {
|
|
// CHECK: entry:
|
|
// CHECK: %0 = load ptr, ptr %dest, align 8
|
|
// CHECK: %1 = load ptr, ptr %src, align 8
|
|
// CHECK: %2 = call ptr @swift_retain(ptr returned %1)
|
|
// CHECK: store ptr %1, ptr %dest, align 8
|
|
// CHECK: call void @swift_release(ptr %0)
|
|
// CHECK: ret ptr %dest
|
|
// CHECK: }
|
|
|
|
// CHECK-LABEL: define internal ptr @"$s34enum_value_semantics_special_cases18NullableRefcountedOwta"(ptr noalias %dest, ptr noalias %src, ptr %NullableRefcounted) {{.*}} {
|
|
// CHECK: entry:
|
|
// CHECK: %0 = load ptr, ptr %dest, align 8
|
|
// CHECK: %1 = load ptr, ptr %src, align 8
|
|
// CHECK: store ptr %1, ptr %dest, align 8
|
|
// CHECK: call void @swift_release(ptr %0)
|
|
// CHECK: ret ptr %dest
|
|
// CHECK: }
|
|
|
|
// Enums consisting of a retainable block pointer and a single empty case use
|
|
// nullable block pointer value semantics.
|
|
enum NullableBlockRefcounted {
|
|
case Ref(@convention(block) () -> ())
|
|
case None
|
|
}
|
|
|
|
// CHECK-LABEL: define internal void @"$s34enum_value_semantics_special_cases23NullableBlockRefcountedOwxx"(ptr noalias %object, ptr %NullableBlockRefcounted) {{.*}} {
|
|
// CHECK: entry:
|
|
// CHECK: %0 = load ptr, ptr %object, align 8
|
|
// CHECK: call void @_Block_release(ptr %0)
|
|
// CHECK: ret void
|
|
// CHECK: }
|
|
|
|
// CHECK-LABEL: define internal ptr @"$s34enum_value_semantics_special_cases23NullableBlockRefcountedOwcp"(ptr noalias %dest, ptr noalias %src, ptr %NullableBlockRefcounted) {{.*}} {
|
|
// CHECK: entry:
|
|
// CHECK: %0 = load ptr, ptr %src, align 8
|
|
// CHECK: %1 = call ptr @_Block_copy(ptr %0)
|
|
// CHECK: store ptr %0, ptr %dest, align 8
|
|
// CHECK: ret ptr %dest
|
|
// CHECK: }
|
|
|
|
// CHECK-LABEL: define internal ptr @"$s34enum_value_semantics_special_cases23NullableBlockRefcountedOwca"(ptr %dest, ptr %src, ptr %NullableBlockRefcounted) {{.*}} {
|
|
// CHECK: entry:
|
|
// CHECK: %0 = load ptr, ptr %dest, align 8
|
|
// CHECK: %1 = load ptr, ptr %src, align 8
|
|
// CHECK: %2 = call ptr @_Block_copy(ptr %1)
|
|
// CHECK: store ptr %1, ptr %dest, align 8
|
|
// CHECK: call void @_Block_release(ptr %0)
|
|
// CHECK: ret ptr %dest
|
|
// CHECK: }
|
|
|
|
// CHECK-LABEL: define internal ptr @"$s34enum_value_semantics_special_cases23NullableBlockRefcountedOwta"(ptr noalias %dest, ptr noalias %src, ptr %NullableBlockRefcounted) {{.*}} {
|
|
// CHECK: entry:
|
|
// CHECK: %0 = load ptr, ptr %dest, align 8
|
|
// CHECK: %1 = load ptr, ptr %src, align 8
|
|
// CHECK: store ptr %1, ptr %dest, align 8
|
|
// CHECK: call void @_Block_release(ptr %0)
|
|
// CHECK: ret ptr %dest
|
|
// CHECK: }
|
|
|
|
// With multiple empty cases, the nullable pointer semantics aren't used.
|
|
enum MultipleEmptyRefcounted {
|
|
case Ref(Builtin.NativeObject)
|
|
case A
|
|
case B
|
|
}
|
|
|
|
// CHECK-LABEL: define internal void @"$s34enum_value_semantics_special_cases23MultipleEmptyRefcountedOwxx"(ptr noalias %object, ptr %MultipleEmptyRefcounted) {{.*}} {
|
|
// CHECK: entry:
|
|
// CHECK: %0 = load i64, ptr %object, align 8
|
|
// CHECK: switch i64 %0, label %1 [
|
|
// CHECK: i64 0, label %2
|
|
// CHECK-native: i64 1, label %2
|
|
// CHECK-objc-simulator-false: i64 2, label %2
|
|
// CHECK-objc-simulator-true: i64 1, label %2
|
|
// CHECK: ]
|
|
// CHECK: 1: ; preds = %entry
|
|
// CHECK: %toDestroy = load ptr, ptr %object, align 8
|
|
// CHECK: call void @swift_release(ptr %toDestroy)
|
|
// CHECK: br label %2
|
|
// CHECK: 2: ; preds = %1, %entry, %entry
|
|
// CHECK: ret void
|
|
// CHECK: }
|
|
|
|
// Enums consisting of all retainable pointers and at most one empty case
|
|
// use tagged pointer value semantics—we mask off the tag bits and pass the
|
|
// pointer to the r/r functions.
|
|
|
|
class C {}
|
|
sil_vtable C {}
|
|
class D {}
|
|
sil_vtable D {}
|
|
|
|
sil @$s34enum_value_semantics_special_cases1CCfD : $@convention(method) (C) -> ()
|
|
sil @$s34enum_value_semantics_special_cases1DCfD : $@convention(method) (D) -> ()
|
|
|
|
enum AllRefcounted {
|
|
case Ref(Builtin.NativeObject)
|
|
case CRef(C)
|
|
case DRef(D)
|
|
case None
|
|
}
|
|
|
|
// CHECK-LABEL: define internal void @"$s34enum_value_semantics_special_cases13AllRefcountedOwxx"(ptr noalias %object, ptr %AllRefcounted) {{.*}} {
|
|
// CHECK: entry:
|
|
// CHECK: %0 = load i64, ptr %object, align 8
|
|
// -- 0x3fffffffffffffff
|
|
// CHECK: %1 = and i64 %0, 4611686018427387903
|
|
// CHECK: %2 = inttoptr i64 %1 to ptr
|
|
// CHECK: call void @swift_release(ptr %2)
|
|
// CHECK: ret void
|
|
// CHECK: }
|
|
|
|
// CHECK-LABEL: define internal ptr @"$s34enum_value_semantics_special_cases13AllRefcountedOwcp"(ptr noalias %dest, ptr noalias %src, ptr %AllRefcounted)
|
|
// -- 0x3fffffffffffffff
|
|
// CHECK: %1 = and i64 %0, 4611686018427387903
|
|
// CHECK: %2 = inttoptr i64 %1 to ptr
|
|
// CHECK: call ptr @swift_retain(ptr returned %2)
|
|
// -- NB: The original loaded value is stored, not the masked one.
|
|
// CHECK: store i64 %0, ptr %dest, align 8
|
|
// CHECK: }
|
|
|
|
enum AllRefcountedTwoSimple {
|
|
case Ref(Builtin.NativeObject)
|
|
case CRef(C)
|
|
case DRef(D)
|
|
case None
|
|
case Nothing
|
|
}
|
|
|
|
// CHECK-LABEL: define internal void @"$s34enum_value_semantics_special_cases22AllRefcountedTwoSimpleOwxx"
|
|
// CHECK: call void @"$s34enum_value_semantics_special_cases22AllRefcountedTwoSimpleOWOy"
|