mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
LoadableByAddress was accidentally changing ownership of direct_unowned values to @in (owned). This generates unsupported SIL for on-stack partial applies, which now breaks SIL verification. This also resulted in extra copies of values inside of closure contexts. Before calling the original function, the value would need to be copied onto the stack and the context would be destroyed. Now, we simply pass a pointer directly from the closure context. See IRGen/indirect_argument.sil+huge_partial_application. I'm pretty sure fixing this has no effect on the mangling of public symbols.
105 lines
6.0 KiB
Plaintext
105 lines
6.0 KiB
Plaintext
// RUN: %target-swift-frontend -Xllvm -sil-disable-pass=OnoneSimplification %s -emit-ir | %FileCheck -check-prefix=CHECK -check-prefix=CHECK-%target-ptrsize %s
|
|
|
|
// UNSUPPORTED: CPU=arm64_32
|
|
|
|
import Swift
|
|
import Builtin
|
|
|
|
struct Huge {
|
|
var x, y, z, w, v: Builtin.Word
|
|
}
|
|
|
|
@_alignment(16)
|
|
struct HugeAlignment {
|
|
var x, y, z, w, v: Builtin.Word
|
|
}
|
|
|
|
// TODO: could be the context param
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @huge_method(ptr noalias nocapture swiftself dereferenceable({{.*}}) %0)
|
|
// CHECK-NOT: alloca
|
|
// CHECK: call swiftcc void @huge_method(ptr noalias nocapture swiftself dereferenceable({{.*}}) %0)
|
|
sil @huge_method : $@convention(method) (Huge) -> () {
|
|
entry(%x : $Huge):
|
|
%f = function_ref @huge_method : $@convention(method) (Huge) -> ()
|
|
%z = apply %f(%x) : $@convention(method) (Huge) -> ()
|
|
return %z : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @huge_param(ptr noalias nocapture dereferenceable({{.*}}) %0)
|
|
// CHECK-NOT: alloca
|
|
// CHECK: call swiftcc void @huge_param(ptr noalias nocapture dereferenceable({{.*}}) %0)
|
|
sil @huge_param : $@convention(thin) (Huge) -> () {
|
|
entry(%x : $Huge):
|
|
%f = function_ref @huge_param : $@convention(thin) (Huge) -> ()
|
|
%z = apply %f(%x) : $@convention(thin) (Huge) -> ()
|
|
return %z : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @huge_alignment_param(ptr noalias nocapture dereferenceable({{.*}}) %0)
|
|
// CHECK-NOT: alloca
|
|
// CHECK: call swiftcc void @huge_alignment_param(ptr noalias nocapture dereferenceable({{.*}}) %0)
|
|
sil @huge_alignment_param : $@convention(thin) (HugeAlignment) -> () {
|
|
entry(%x : $HugeAlignment):
|
|
%f = function_ref @huge_alignment_param : $@convention(thin) (HugeAlignment) -> ()
|
|
%z = apply %f(%x) : $@convention(thin) (HugeAlignment) -> ()
|
|
return %z : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @huge_param_and_return(ptr noalias nocapture sret({{.*}}) %0, ptr noalias nocapture dereferenceable({{.*}}) %1)
|
|
// CHECK: [[TMP_RET:%.*]] = alloca
|
|
// CHECK: call swiftcc void @huge_param_and_return(ptr noalias nocapture sret({{.*}}) [[TMP_RET]], ptr noalias nocapture dereferenceable({{.*}}) %1)
|
|
sil @huge_param_and_return : $@convention(thin) (Huge) -> Huge {
|
|
entry(%x : $Huge):
|
|
%f = function_ref @huge_param_and_return : $@convention(thin) (Huge) -> Huge
|
|
%z = apply %f(%x) : $@convention(thin) (Huge) -> Huge
|
|
return %z : $Huge
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @huge_param_and_indirect_return(ptr noalias nocapture sret({{.*}}) %0, ptr noalias nocapture dereferenceable({{.*}}) %1)
|
|
// CHECK-NOT: alloca
|
|
// CHECK: call swiftcc void @huge_param_and_indirect_return(ptr noalias nocapture sret({{.*}}) %0, ptr noalias nocapture dereferenceable({{.*}}) %1)
|
|
sil @huge_param_and_indirect_return : $@convention(thin) (Huge) -> @out Huge {
|
|
entry(%o : $*Huge, %x : $Huge):
|
|
%f = function_ref @huge_param_and_indirect_return : $@convention(thin) (Huge) -> @out Huge
|
|
%z = apply %f(%o, %x) : $@convention(thin) (Huge) -> @out Huge
|
|
return %z : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @huge_partial_application(ptr noalias nocapture dereferenceable({{.*}}) %0, ptr noalias nocapture dereferenceable({{.*}}) %1)
|
|
// CHECK-NOT: alloca
|
|
// CHECK: [[CLOSURE:%.*]] = call noalias ptr @swift_allocObject
|
|
// CHECK: call swiftcc {{.*}} @"$s24huge_partial_applicationTA{{(\.ptrauth)?}}"{{.*}}(ptr noalias nocapture dereferenceable({{.*}}) %0, ptr swiftself [[CLOSURE]])
|
|
// CHECK: define internal swiftcc void @"$s24huge_partial_applicationTA"(ptr noalias nocapture dereferenceable({{.*}}) %0, ptr swiftself %1)
|
|
// CHECK-NOT: alloca
|
|
// CHECK: [[GEP:%.*]] = getelementptr inbounds <{ %swift.refcounted, %T17indirect_argument4HugeV }>, ptr %1, i32 0, i32 1
|
|
// CHECK-NOT: alloca
|
|
// CHECK-NOT: tail
|
|
// CHECK: call swiftcc void @huge_partial_application(ptr noalias nocapture dereferenceable({{.*}}) %0, ptr noalias nocapture dereferenceable({{.*}}) [[GEP]]
|
|
// CHECK: call void @swift_release(ptr %1)
|
|
sil @huge_partial_application : $@convention(thin) (Huge, Huge) -> () {
|
|
entry(%x : $Huge, %y : $Huge):
|
|
%f = function_ref @huge_partial_application : $@convention(thin) (Huge, Huge) -> ()
|
|
%a = partial_apply %f(%y) : $@convention(thin) (Huge, Huge) -> ()
|
|
%z = apply %a(%x) : $@convention(thick) @callee_owned (Huge) -> ()
|
|
return %z : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @huge_partial_application_stret(ptr noalias nocapture sret({{.*}}) %0, ptr noalias nocapture dereferenceable({{.*}}) %1, ptr noalias nocapture dereferenceable({{.*}}) %2)
|
|
// CHECK: [[TMP_RET:%.*]] = alloca
|
|
// CHECK: [[CLOSURE:%.*]] = call noalias ptr @swift_allocObject
|
|
// CHECK: call swiftcc {{.*}} @"$s30huge_partial_application_stretTA{{(\.ptrauth)?}}"{{.*}}(ptr noalias nocapture sret({{.*}}) [[TMP_RET]], ptr noalias nocapture dereferenceable({{.*}}) %1, ptr swiftself [[CLOSURE]])
|
|
// CHECK: define internal swiftcc void @"$s30huge_partial_application_stretTA"(ptr noalias nocapture sret({{.*}}) %0, ptr noalias nocapture dereferenceable({{.*}}) %1, ptr swiftself %2)
|
|
// CHECK-NOT: alloca
|
|
// CHECK: [[GEP:%.*]] = getelementptr inbounds <{ %swift.refcounted, %T17indirect_argument4HugeV }>, ptr %2, i32 0, i32 1
|
|
// CHECK-NOT: alloca
|
|
// CHECK-NOT: tail
|
|
// CHECK: call swiftcc void @huge_partial_application_stret(ptr noalias nocapture sret({{.*}}) %0, ptr noalias nocapture dereferenceable({{.*}}) %1, ptr noalias nocapture dereferenceable({{.*}}) [[GEP]])
|
|
// CHECK: call void @swift_release(ptr %2)
|
|
sil @huge_partial_application_stret : $@convention(thin) (Huge, Huge) -> Huge {
|
|
entry(%x : $Huge, %y : $Huge):
|
|
%f = function_ref @huge_partial_application_stret : $@convention(thin) (Huge, Huge) -> Huge
|
|
%a = partial_apply %f(%y) : $@convention(thin) (Huge, Huge) -> Huge
|
|
%z = apply %a(%x) : $@convention(thick) @callee_owned (Huge) -> Huge
|
|
return %z : $Huge
|
|
}
|