Files
swift-mirror/test/SILGen/toplevel_globalactorvars.swift
Kavon Farvardin 06ac850d74 [SILGen] avoid hop before autoreleased foreign error is retained
For an isolated ObjC function that is not async, we
emit a hops around the call. But if that function
returns an autoreleased pointer, we need to ensure
we're retaining that pointer before hopping back
after the call. We weren't doing that in the case
of an autoreleased NSError:

```
%10 = alloc_stack $@sil_unmanaged Optional<NSError>
%19 = ... a bunch of steps to wrap up %10 ...
%20 = enum $Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>, #Optional.some!enumelt, %19 : $AutoreleasingUnsafeMutablePointer<Optional<NSError>>
hop_to_executor $MainActor
%26 = apply X(Y, %20) : $@convention(objc_method) (NSObject, Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>) -> @autoreleased Optional<NSString>
hop_to_executor $Optional<Builtin.Executor>
// retain the autoreleased pointer written-out.
%28 = load [trivial] %10 : $*@sil_unmanaged Optional<NSError>
%29 = unmanaged_to_ref %28 : $@sil_unmanaged Optional<NSError> to $Optional<NSError>
%30 = copy_value %29 : $Optional<NSError>
assign %31 to %7 : $*Optional<NSError>
```

This patch sinks the hop emission after the call
so it happens after doing that copy.

rdar://114049646
2023-12-19 13:16:59 -08:00

126 lines
5.0 KiB
Swift

// RUN: %target-swift-emit-silgen -Xllvm -sil-full-demangle -disable-availability-checking -enable-experimental-async-top-level %s | %FileCheck %s
// a
// CHECK-LABEL: sil_global hidden @$s24toplevel_globalactorvars1aSivp : $Int
// CHECK-LABEL: sil private [ossa] @async_Main
// CHECK: bb0:
// CHECK-NEXT: [[MAIN:%.*]] = builtin "buildMainActorExecutorRef"() : $Builtin.Executor
// CHECK-NEXT: [[MAIN_OPTIONAL:%[0-9]+]] = enum $Optional<Builtin.Executor>, #Optional.some!enumelt, [[MAIN]]
actor MyActorImpl {}
@globalActor
struct MyActor {
static let shared = MyActorImpl()
}
var a = 10
// a initialization
// CHECK: alloc_global @$s24toplevel_globalactorvars1aSivp
// CHECK: [[AREF:%[0-9]+]] = global_addr @$s24toplevel_globalactorvars1aSivp
// CHECK: [[TEN_LIT:%[0-9]+]] = integer_literal $Builtin.IntLiteral, 10
// CHECK: [[INT_TYPE:%[0-9]+]] = metatype $@thin Int.Type
// CHECK: [[INT_INIT:%[0-9]+]] = function_ref @$sSi22_builtinIntegerLiteralSiBI_tcfC
// CHECK: [[TEN:%[0-9]+]] = apply [[INT_INIT]]([[TEN_LIT]], [[INT_TYPE]])
// CHECK: store [[TEN]] to [trivial] [[AREF]]
@MyActor
func printFromMyActor(value : Int) {
print(value)
}
print(a)
// print
// CHECK-NOT: hop_to_executor
// CHECK: [[AACCESS:%[0-9]+]] = begin_access [read] [dynamic] [[AREF]] : $*Int
// CHECK: [[AGLOBAL:%[0-9]+]] = load [trivial] [[AACCESS]] : $*Int
// CHECK: end_access [[AACCESS]]
// CHECK-NOT: hop_to_executor
a += 1
// CHECK: [[ONE_LIT:%[0-9]+]] = integer_literal $Builtin.IntLiteral, 1
// CHECK: [[INT_TYPE:%[0-9]+]] = metatype $@thin Int.Type
// CHECK: [[INT_INIT:%[0-9]+]] = function_ref @$sSi22_builtinIntegerLiteralSiBI_tcfC
// CHECK: [[ONE:%[0-9]+]] = apply [[INT_INIT]]([[ONE_LIT]], [[INT_TYPE]])
// CHECK-NOT: hop_to_executor
// CHECK: [[AACCESS:%[0-9]+]] = begin_access [modify] [dynamic] [[AREF]] : $*Int
// static Int.+= infix(_:_:)
// CHECK: [[PE_INT_FUNC:%[0-9]+]] = function_ref @$sSi2peoiyySiz_SitFZ
// CHECK: [[INCREMENTED:%[0-9]+]] = apply [[PE_INT_FUNC]]([[AACCESS]], [[ONE]], {{%[0-9]+}})
// CHECK: end_access [[AACCESS]]
// CHECK-NOT: hop_to_executor
await printFromMyActor(value: a)
// CHECK: [[AACCESS:%[0-9]+]] = begin_access [read] [dynamic] [[AREF]] : $*Int
// CHECK: [[AGLOBAL:%[0-9]+]] = load [trivial] [[AACCESS]] : $*Int
// CHECK: end_access [[AACCESS]]
// CHECK: [[PRINTFROMMYACTOR_FUNC:%[0-9]+]] = function_ref @$s24toplevel_globalactorvars16printFromMyActor5valueySi_tF
// CHECK: [[ACTORREF:%[0-9]+]] = begin_borrow {{%[0-9]+}} : $MyActorImpl
// CHECK: hop_to_executor [[ACTORREF]] : $MyActorImpl
// CHECK: {{%[0-9]+}} = apply [[PRINTFROMMYACTOR_FUNC]]([[AGLOBAL]])
// CHECK: end_borrow [[ACTORREF]]
// CHECK: hop_to_executor [[MAIN_OPTIONAL]]
if a < 10 {
// CHECK: [[AACCESS:%[0-9]+]] = begin_access [read] [dynamic] [[AREF]] : $*Int
// CHECK: [[AGLOBAL:%[0-9]+]] = load [trivial] [[AACCESS]] : $*Int
// CHECK: end_access [[AACCESS]]
// CHECK: [[TEN_LIT:%[0-9]+]] = integer_literal $Builtin.IntLiteral, 10
// CHECK: [[INT_TYPE:%[0-9]+]] = metatype $@thin Int.Type
// CHECK: [[INT_INIT:%[0-9]+]] = function_ref @$sSi22_builtinIntegerLiteralSiBI_tcfC
// CHECK: [[TEN:%[0-9]+]] = apply [[INT_INIT]]([[TEN_LIT]], [[INT_TYPE]])
// function_ref static Swift.Int.< infix(Swift.Int, Swift.Int) -> Swift.Bool
// CHECK: [[LESS_FUNC:%[0-9]+]] = function_ref @$sSi1loiySbSi_SitFZ
// CHECK: [[WRAPPED_COND:%[0-9]+]] = apply [[LESS_FUNC]]([[AGLOBAL]], [[TEN]], {{%[0-9]+}})
// CHECK: [[COND:%[0-9]+]] = struct_extract [[WRAPPED_COND]]
// CHECK: cond_br [[COND]], bb1, bb2
// CHECK: bb1:
print(a)
// print
// CHECK-NOT: hop_to_executor
// CHECK: [[AACCESS:%[0-9]+]] = begin_access [read] [dynamic] [[AREF]] : $*Int
// CHECK: [[AGLOBAL:%[0-9]+]] = load [trivial] [[AACCESS]] : $*Int
// CHECK: end_access [[AACCESS]]
// CHECK-NOT: hop_to_executor
a += 1
// CHECK: [[ONE_LIT:%[0-9]+]] = integer_literal $Builtin.IntLiteral, 1
// CHECK: [[INT_TYPE:%[0-9]+]] = metatype $@thin Int.Type
// CHECK: [[INT_INIT:%[0-9]+]] = function_ref @$sSi22_builtinIntegerLiteralSiBI_tcfC
// CHECK: [[ONE:%[0-9]+]] = apply [[INT_INIT]]([[ONE_LIT]], [[INT_TYPE]])
// CHECK-NOT: hop_to_executor
// CHECK: [[AACCESS:%[0-9]+]] = begin_access [modify] [dynamic] [[AREF]] : $*Int
// static Int.+= infix(_:_:)
// CHECK: [[PE_INT_FUNC:%[0-9]+]] = function_ref @$sSi2peoiyySiz_SitFZ
// CHECK: [[INCREMENTED:%[0-9]+]] = apply [[PE_INT_FUNC]]([[AACCESS]], [[ONE]], {{%[0-9]+}})
// CHECK: end_access [[AACCESS]]
// CHECK-NOT: hop_to_executor
await printFromMyActor(value: a)
// CHECK: [[AACCESS:%[0-9]+]] = begin_access [read] [dynamic] [[AREF]] : $*Int
// CHECK: [[AGLOBAL:%[0-9]+]] = load [trivial] [[AACCESS]] : $*Int
// CHECK: end_access [[AACCESS]]
// CHECK: [[PRINTFROMMYACTOR_FUNC:%[0-9]+]] = function_ref @$s24toplevel_globalactorvars16printFromMyActor5valueySi_tF
// CHECK: [[ACTORREF:%[0-9]+]] = begin_borrow {{%[0-9]+}} : $MyActorImpl
// CHECK: hop_to_executor [[ACTORREF]] : $MyActorImpl
// CHECK: {{%[0-9]+}} = apply [[PRINTFROMMYACTOR_FUNC]]([[AGLOBAL]])
// CHECK: end_borrow [[ACTORREF]]
// CHECK: hop_to_executor [[MAIN_OPTIONAL]]
}