mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
254 lines
12 KiB
Plaintext
254 lines
12 KiB
Plaintext
// RUN: %target-swift-frontend -enable-objc-interop -stack-promotion-limit 48 -Onone -emit-ir %s | %FileCheck --check-prefixes=CHECK,CHECK-objc %s -DINT=i%target-ptrsize
|
|
// RUN: %target-swift-frontend -disable-objc-interop -stack-promotion-limit 48 -Onone -emit-ir %s | %FileCheck --check-prefixes=CHECK,CHECK-native %s -DINT=i%target-ptrsize
|
|
//
|
|
// REQUIRES: CPU=x86_64
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
// sizeof(TestClass) = 16 bytes header + 1 byte = 17 bytes
|
|
class TestClass {
|
|
@_hasStorage var a : Int8
|
|
init()
|
|
}
|
|
|
|
sil_vtable TestClass {}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @alloc_on_stack
|
|
// CHECK: %reference.raw = alloca i8, i32 28, align 8
|
|
// CHECK-NEXT: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s{{[a-zA-Z0-9_]+}}Ma"([[INT]] 0)
|
|
// CHECK-NEXT: [[M:%[0-9]+]] = extractvalue %swift.metadata_response [[TMP]], 0
|
|
// CHECK-NEXT: %reference.new = call ptr @swift_initStackObject(ptr [[M]], ptr %reference.raw)
|
|
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr %reference.new)
|
|
// CHECK-NEXT: ret void
|
|
sil @alloc_on_stack : $@convention(thin) () -> () {
|
|
bb0:
|
|
%c = integer_literal $Builtin.Word, 2 // size = 17 + 3(padding) + 2 * 4 = 28
|
|
%o1 = alloc_ref [stack] [tail_elems $Int32 * %c : $Builtin.Word] $TestClass
|
|
dealloc_stack_ref %o1 : $TestClass
|
|
%r = tuple()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @alloc_on_heap
|
|
// CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s{{[a-zA-Z0-9_]+}}Ma"([[INT]] 0)
|
|
// CHECK: [[M:%[0-9]+]] = extractvalue %swift.metadata_response [[TMP]], 0
|
|
// CHECK-NEXT: [[O:%[0-9]+]] = call noalias ptr @swift_allocObject(ptr [[M]], i64 28, i64 7)
|
|
// CHECK-NEXT: ret ptr [[O]]
|
|
sil @alloc_on_heap : $@convention(thin) () -> @owned TestClass {
|
|
bb0:
|
|
%c = integer_literal $Builtin.Word, 2 // size = 17 + 3(padding) + 2 * 4 = 28
|
|
%o1 = alloc_ref [tail_elems $Int32 * %c : $Builtin.Word] $TestClass
|
|
return %o1 : $TestClass
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @alloc_3_on_heap
|
|
// CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s{{[a-zA-Z0-9_]+}}CMa"([[INT]] 0)
|
|
// CHECK: [[M:%[0-9]+]] = extractvalue %swift.metadata_response [[TMP]], 0
|
|
// CHECK-NEXT: [[O:%[0-9]+]] = call noalias ptr @swift_allocObject(ptr [[M]], i64 40, i64 7)
|
|
// CHECK-NEXT: ret ptr [[O]]
|
|
sil @alloc_3_on_heap : $@convention(thin) () -> @owned TestClass {
|
|
bb0:
|
|
%c1 = integer_literal $Builtin.Word, 2 // size = 17 + 2 = 19
|
|
%c2 = integer_literal $Builtin.Word, 5 // size = 19 + 1(padding) + 5 * 2 = 30
|
|
%c3 = integer_literal $Builtin.Word, 1 // size = 30 + 2(padding) + 8 = 40
|
|
%o1 = alloc_ref [tail_elems $Int8 * %c1 : $Builtin.Word] [tail_elems $Int16 * %c2 : $Builtin.Word] [tail_elems $Int64 * %c3 : $Builtin.Word] $TestClass
|
|
return %o1 : $TestClass
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @alloc_non_const_count
|
|
// CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s{{[a-zA-Z0-9_]+}}Ma"([[INT]] 0)
|
|
// CHECK: [[M:%[0-9]+]] = extractvalue %swift.metadata_response [[TMP]], 0
|
|
// CHECK-NEXT: [[S:%[0-9]+]] = mul i64 4, %0
|
|
// CHECK-NEXT: [[A:%[0-9]+]] = add i64 20, [[S]]
|
|
// CHECK-NEXT: [[O:%[0-9]+]] = call noalias ptr @swift_allocObject(ptr [[M]], i64 [[A]], i64 7)
|
|
// CHECK-NEXT: ret ptr [[O]]
|
|
sil @alloc_non_const_count : $@convention(thin) (Builtin.Word) -> @owned TestClass {
|
|
bb0(%c : $Builtin.Word):
|
|
%o1 = alloc_ref [tail_elems $Int32 * %c : $Builtin.Word] $TestClass
|
|
return %o1 : $TestClass
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @alloc_2_non_const_count
|
|
// CHECK: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s{{[a-zA-Z0-9_]+}}Ma"([[INT]] 0)
|
|
// CHECK: [[M:%[0-9]+]] = extractvalue %swift.metadata_response [[TMP]], 0
|
|
// CHECK-NEXT: [[S1:%[0-9]+]] = mul i64 1, %0
|
|
// CHECK-NEXT: [[S2:%[0-9]+]] = add i64 17, [[S1]]
|
|
// CHECK-NEXT: [[S3:%[0-9]+]] = add i64 [[S2]], 3
|
|
// CHECK-NEXT: [[S4:%[0-9]+]] = and i64 [[S3]], -4
|
|
// CHECK-NEXT: [[S5:%[0-9]+]] = mul i64 4, %1
|
|
// CHECK-NEXT: [[S6:%[0-9]+]] = add i64 [[S4]], [[S5]]
|
|
// CHECK-NEXT: [[O:%[0-9]+]] = call noalias ptr @swift_allocObject(ptr [[M]], i64 [[S6]], i64 7)
|
|
// CHECK-NEXT: ret ptr [[O]]
|
|
sil @alloc_2_non_const_count : $@convention(thin) (Builtin.Word, Builtin.Word) -> @owned TestClass {
|
|
bb0(%c1 : $Builtin.Word, %c2 : $Builtin.Word):
|
|
%o1 = alloc_ref [tail_elems $Int8 * %c1 : $Builtin.Word] [tail_elems $Int32 * %c2 : $Builtin.Word] $TestClass
|
|
return %o1 : $TestClass
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @alloc_generic
|
|
// CHECK: [[S1:%[0-9]+]] = add i64 17, %flags.alignmentMask
|
|
// CHECK-NEXT: [[S2:%[0-9]+]] = xor i64 %flags.alignmentMask, -1
|
|
// CHECK-NEXT: [[S3:%[0-9]+]] = and i64 [[S1]], [[S2]]
|
|
// CHECK-NEXT: [[S4:%[0-9]+]] = mul i64 %stride, %0
|
|
// CHECK-NEXT: [[S5:%[0-9]+]] = add i64 [[S3]], [[S4]]
|
|
// CHECK-NEXT: [[A:%[0-9]+]] = or i64 7, %flags.alignmentMask
|
|
// CHECK: call noalias ptr @swift_allocObject(ptr %{{[0-9]+}}, i64 [[S5]], i64 [[A]])
|
|
// CHECK: ret
|
|
sil @alloc_generic : $@convention(thin) <T> (Builtin.Word, @thick T.Type) -> @owned TestClass {
|
|
bb0(%0 : $Builtin.Word, %1 : $@thick T.Type):
|
|
%4 = metatype $@thick TestClass.Type
|
|
%5 = alloc_ref [tail_elems $T * %0 : $Builtin.Word] $TestClass
|
|
return %5 : $TestClass
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @alloc_dynamic
|
|
// CHECK-objc: [[SIZE_ADDR:%[0-9]+]] = getelementptr inbounds i8, ptr %0, i32 48
|
|
// CHECK-native: [[SIZE_ADDR:%[0-9]+]] = getelementptr inbounds i8, ptr %0, i32 24
|
|
// CHECK-NEXT: [[SIZE:%[0-9]+]] = load i32, ptr [[SIZE_ADDR]]
|
|
// CHECK-NEXT: [[SIZE64:%[0-9]+]] = zext i32 [[SIZE]] to i64
|
|
// CHECK-objc-NEXT: [[ALIGN_ADDR:%[0-9]+]] = getelementptr inbounds i8, ptr %0, i32 52
|
|
// CHECK-native-NEXT: [[ALIGN_ADDR:%[0-9]+]] = getelementptr inbounds i8, ptr %0, i32 28
|
|
// CHECK-NEXT: [[ALIGN:%[0-9]+]] = load i16, ptr [[ALIGN_ADDR]]
|
|
// CHECK-NEXT: [[ALIGN64:%[0-9]+]] = zext i16 [[ALIGN]] to i64
|
|
// CHECK-NEXT: [[ALIGN_TMP:%[0-9]+]] = add i64 [[SIZE64]], 3
|
|
// CHECK-NEXT: [[ALIGNED:%[0-9]+]] = and i64 [[ALIGN_TMP]], -4
|
|
// CHECK-NEXT: [[TOTAL_SIZE:%[0-9]+]] = add i64 [[ALIGNED]], 12
|
|
// CHECK-NEXT: [[TOTAL_ALIGN:%[0-9]+]] = or i64 [[ALIGN64]], 3
|
|
// CHECK-NEXT: [[O:%[0-9]+]] = call noalias ptr @swift_allocObject(ptr %0, i64 [[TOTAL_SIZE]], i64 [[TOTAL_ALIGN]])
|
|
// CHECK-NEXT: ret ptr [[O]]
|
|
sil @alloc_dynamic : $@convention(thin) (@thick TestClass.Type) -> @owned TestClass {
|
|
bb0(%0 : $@thick TestClass.Type):
|
|
%c = integer_literal $Builtin.Word, 3
|
|
%o = alloc_ref_dynamic [tail_elems $Int32 * %c : $Builtin.Word] %0 : $@thick TestClass.Type, $TestClass
|
|
return %o : $TestClass
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @project_tail_byte
|
|
// CHECK: getelementptr inbounds i8, ptr %{{[0-9]+}}, i64 17
|
|
// CHECK: ret
|
|
sil @project_tail_byte : $@convention(thin) (TestClass) -> Builtin.RawPointer {
|
|
bb0(%0 : $TestClass):
|
|
%a = ref_tail_addr %0 : $TestClass, $Int8
|
|
%p = address_to_pointer %a : $*Int8 to $Builtin.RawPointer
|
|
return %p : $Builtin.RawPointer
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @project_tail_int
|
|
// CHECK: [[S:%[0-9]+]] = getelementptr inbounds i8, ptr %{{[0-9]+}}, i64 20
|
|
// CHECK: ret
|
|
sil @project_tail_int : $@convention(thin) (TestClass, Int32) -> () {
|
|
bb0(%0 : $TestClass, %1 : $Int32):
|
|
%a = ref_tail_addr %0 : $TestClass, $Int32
|
|
store %1 to %a : $*Int32
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @project_tail_generic
|
|
// CHECK: [[S1:%[0-9]+]] = add i64 17, %flags.alignmentMask
|
|
// CHECK-NEXT: [[S2:%[0-9]+]] = xor i64 %flags.alignmentMask, -1
|
|
// CHECK-NEXT: [[S3:%[0-9]+]] = and i64 [[S1]], [[S2]]
|
|
// CHECK-NEXT: [[S5:%[0-9]+]] = getelementptr inbounds i8, ptr %0, i64 [[S3]]
|
|
// CHECK: ret
|
|
sil @project_tail_generic : $@convention(thin) <T> (TestClass, @thick T.Type) -> Builtin.RawPointer {
|
|
bb0(%0 : $TestClass, %1 : $@thick T.Type):
|
|
%a = ref_tail_addr %0 : $TestClass, $T
|
|
%p = address_to_pointer %a : $*T to $Builtin.RawPointer
|
|
return %p : $Builtin.RawPointer
|
|
}
|
|
|
|
struct Str<T> {
|
|
var t: T
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @project_tail_generic_struct
|
|
// CHECK: [[S1:%[0-9]+]] = add i64 17, %flags.alignmentMask
|
|
// CHECK-NEXT: [[S2:%[0-9]+]] = xor i64 %flags.alignmentMask, -1
|
|
// CHECK-NEXT: [[S3:%[0-9]+]] = and i64 [[S1]], [[S2]]
|
|
// CHECK-NEXT: [[S5:%[0-9]+]] = getelementptr inbounds i8, ptr %0, i64 [[S3]]
|
|
// CHECK: ret
|
|
sil @project_tail_generic_struct : $@convention(thin) <T> (TestClass, @thick T.Type) -> Builtin.RawPointer {
|
|
bb0(%0 : $TestClass, %1 : $@thick T.Type):
|
|
%a = ref_tail_addr %0 : $TestClass, $Str<T>
|
|
%p = address_to_pointer %a : $*Str<T> to $Builtin.RawPointer
|
|
return %p : $Builtin.RawPointer
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @project_tail_index_byte_to_int
|
|
// CHECK: [[S2:%[0-9]+]] = getelementptr inbounds %Ts4Int8V, ptr %0, i64 2
|
|
// CHECK-NEXT: [[S3:%[0-9]+]] = ptrtoint ptr [[S2]] to i64
|
|
// CHECK-NEXT: [[S4:%[0-9]+]] = add nuw i64 [[S3]], 3
|
|
// CHECK-NEXT: [[S5:%[0-9]+]] = and i64 [[S4]], -4
|
|
// CHECK-NEXT: [[S6:%[0-9]+]] = inttoptr i64 [[S5]] to ptr
|
|
// CHECK: ret
|
|
sil @project_tail_index_byte_to_int : $@convention(thin) (Builtin.RawPointer, Int32) -> () {
|
|
bb0(%0 : $Builtin.RawPointer, %1 : $Int32):
|
|
%a1 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*Int8
|
|
%c = integer_literal $Builtin.Word, 2
|
|
%a2 = tail_addr %a1 : $*Int8, %c : $Builtin.Word, $Int32
|
|
store %1 to %a2 : $*Int32
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @project_tail_index_generic_struct
|
|
// CHECK: call swiftcc %swift.metadata_response @{{.*Str.*}}([[INT]] 0, ptr %T)
|
|
// CHECK: load
|
|
// CHECK: and
|
|
// CHECK: xor
|
|
// CHECK: and
|
|
// CHECK: ret
|
|
sil @project_tail_index_generic_struct : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> Builtin.RawPointer {
|
|
bb0(%0 : $Builtin.RawPointer, %1 : $@thick T.Type):
|
|
%a1 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*Int8
|
|
%c = integer_literal $Builtin.Word, 2
|
|
%a2 = tail_addr %a1 : $*Int8, %c : $Builtin.Word, $Str<T>
|
|
%p = address_to_pointer %a2 : $*Str<T> to $Builtin.RawPointer
|
|
return %p : $Builtin.RawPointer
|
|
}
|
|
|
|
// sizeof(EmptyClass) = 16 bytes
|
|
class EmptyClass {
|
|
}
|
|
|
|
sil_vtable EmptyClass {}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i8 @test_align_1_int8
|
|
// CHECK: load i8, ptr %{{.*}}, align 1
|
|
// CHECK: ret
|
|
sil @test_align_1_int8 : $@convention(thin) (EmptyClass) -> Int8 {
|
|
bb0(%0 : $EmptyClass):
|
|
%a = ref_tail_addr %0 : $EmptyClass, $Int8
|
|
%w = integer_literal $Builtin.Word, 1
|
|
%i = index_addr %a : $*Int8, %w : $Builtin.Word
|
|
%l = load %i : $*Int8
|
|
return %l : $Int8
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i8 @test_align_2_int8
|
|
// CHECK: load i8, ptr %{{.*}}, align 2
|
|
// CHECK: ret
|
|
sil @test_align_2_int8 : $@convention(thin) (EmptyClass) -> Int8 {
|
|
bb0(%0 : $EmptyClass):
|
|
%a = ref_tail_addr %0 : $EmptyClass, $Int8
|
|
%w = integer_literal $Builtin.Word, 2
|
|
%i = index_addr %a : $*Int8, %w : $Builtin.Word
|
|
%l = load %i : $*Int8
|
|
return %l : $Int8
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc i32 @test_align_int32
|
|
// CHECK: load i32, ptr %{{.*}}, align 4
|
|
// CHECK: ret
|
|
sil @test_align_int32 : $@convention(thin) (EmptyClass, Builtin.Word) -> Int32 {
|
|
bb0(%0 : $EmptyClass, %1 : $Builtin.Word):
|
|
%a = ref_tail_addr %0 : $EmptyClass, $Int32
|
|
%i = index_addr %a : $*Int32, %1 : $Builtin.Word
|
|
%l = load %i : $*Int32
|
|
return %l : $Int32
|
|
}
|
|
|