Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions include/swift/AST/IRGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,9 @@ class IRGenOptions {

unsigned EmitAsyncFramePushPopMetadata : 1;

// Whether to emit typed malloc during coroutine frame allocation.
unsigned EmitTypeMallocForCoroFrame : 1;

// Whether to use the yield_once ABI when emitting yield_once_2 coroutines.
unsigned EmitYieldOnce2AsYieldOnce : 1;

Expand Down Expand Up @@ -597,8 +600,9 @@ class IRGenOptions {
DisableReadonlyStaticObjects(false), CollocatedMetadataFunctions(false),
ColocateTypeDescriptors(true), UseRelativeProtocolWitnessTables(false),
UseFragileResilientProtocolWitnesses(false), EnableHotColdSplit(false),
EmitAsyncFramePushPopMetadata(true), EmitYieldOnce2AsYieldOnce(true),
AsyncFramePointerAll(false), UseProfilingMarkerThunks(false),
EmitAsyncFramePushPopMetadata(true), EmitTypeMallocForCoroFrame(false),
EmitYieldOnce2AsYieldOnce(true), AsyncFramePointerAll(false),
UseProfilingMarkerThunks(false),
DebugInfoForProfiling(false), CmdArgs(),
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
TypeInfoFilter(TypeInfoDumpFilter::All),
Expand Down
7 changes: 7 additions & 0 deletions include/swift/Option/FrontendOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -1341,6 +1341,13 @@ def disable_async_frame_push_pop_metadata :
Flag<["-"], "disable-async-frame-push-pop-metadata">,
HelpText<"Disable async frame push pop metadata">;

def enable_emit_type_malloc_for_coro_frame :
Flag<["-"], "enable-emit-type-malloc-for-coro-frame">,
HelpText<"Enable emitting typed malloc for coroutine frame allocation">;
def disable_emit_type_malloc_for_coro_frame :
Flag<["-"], "disable-emit-type-malloc-for-coro-frame">,
HelpText<"Disable emitting typed malloc for coroutine frame allocation">;

def enable_async_frame_pointer_all :
Flag<["-"], "enable-async-frame-pointer-all">,
HelpText<"Always emit async frame stack frames (frame-pointer=all)">;
Expand Down
4 changes: 4 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3627,6 +3627,10 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
Args.hasFlag(OPT_enable_async_frame_push_pop_metadata,
OPT_disable_async_frame_push_pop_metadata,
Opts.EmitAsyncFramePushPopMetadata);
Opts.EmitTypeMallocForCoroFrame =
Args.hasFlag(OPT_enable_emit_type_malloc_for_coro_frame,
OPT_disable_emit_type_malloc_for_coro_frame,
Opts.EmitTypeMallocForCoroFrame);
Opts.AsyncFramePointerAll = Args.hasFlag(OPT_enable_async_frame_pointer_all,
OPT_disable_async_frame_pointer_all,
Opts.AsyncFramePointerAll);
Expand Down
41 changes: 31 additions & 10 deletions lib/IRGen/GenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4822,20 +4822,41 @@ emitRetconCoroutineEntry(IRGenFunction &IGF, CanSILFunctionType fnType,
auto prototype =
IGF.IGM.getOpaquePtr(IGF.IGM.getAddrOfContinuationPrototype(fnType));

// Use malloc and free as our allocator.
auto allocFn = IGF.IGM.getOpaquePtr(IGF.IGM.getMallocFn());


// Use free as our deallocator.
auto deallocFn = IGF.IGM.getOpaquePtr(IGF.IGM.getFreeFn());

// Call the right 'llvm.coro.id.retcon' variant.
llvm::Value *buffer = emission.getCoroutineBuffer();
llvm::Value *id = IGF.Builder.CreateIntrinsicCall(idIntrinsic, {
llvm::ConstantInt::get(IGF.IGM.Int32Ty, bufferSize.getValue()),
llvm::ConstantInt::get(IGF.IGM.Int32Ty, bufferAlignment.getValue()),
buffer,
prototype,
allocFn,
deallocFn
});

llvm::Value *id;
if (IGF.getOptions().EmitTypeMallocForCoroFrame) {
// Use swift_coroFrameAlloc as our allocator.
auto coroAllocFn = IGF.IGM.getOpaquePtr(IGF.IGM.getCoroFrameAllocFn());
auto mallocTypeId = IGF.getMallocTypeId();
id = IGF.Builder.CreateIntrinsicCall(idIntrinsic, {
llvm::ConstantInt::get(IGF.IGM.Int32Ty, bufferSize.getValue()),
llvm::ConstantInt::get(IGF.IGM.Int32Ty, bufferAlignment.getValue()),
buffer,
prototype,
coroAllocFn,
deallocFn,
mallocTypeId
});
} else {
// Use mallocas our allocator.
auto allocFn = IGF.IGM.getOpaquePtr(IGF.IGM.getMallocFn());
id = IGF.Builder.CreateIntrinsicCall(idIntrinsic, {
llvm::ConstantInt::get(IGF.IGM.Int32Ty, bufferSize.getValue()),
llvm::ConstantInt::get(IGF.IGM.Int32Ty, bufferAlignment.getValue()),
buffer,
prototype,
allocFn,
deallocFn
});
}


// Call 'llvm.coro.begin', just for consistency with the normal pattern.
// This serves as a handle that we can pass around to other intrinsics.
Expand Down
24 changes: 21 additions & 3 deletions lib/IRGen/GenFunc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1459,13 +1459,30 @@ class CoroPartialApplicationForwarderEmission
cast<SILFunctionType>(
unsubstType->mapTypeOutOfContext()->getCanonicalType())));

// Use malloc and free as our allocator.
auto allocFn = subIGF.IGM.getOpaquePtr(subIGF.IGM.getMallocFn());

// Use free as our allocator.
auto deallocFn = subIGF.IGM.getOpaquePtr(subIGF.IGM.getFreeFn());

// Call the right 'llvm.coro.id.retcon' variant.
llvm::Value *buffer = origParams.claimNext();
llvm::Value *id = subIGF.Builder.CreateIntrinsicCall(
llvm::Value *id;
if (subIGF.IGM.getOptions().EmitTypeMallocForCoroFrame) {
// Use swift_coroFrameAlloc as our allocator.
auto coroAllocFn = subIGF.IGM.getOpaquePtr(subIGF.IGM.getCoroFrameAllocFn());
auto mallocTypeId = subIGF.getMallocTypeId();
id = subIGF.Builder.CreateIntrinsicCall(
llvm::Intrinsic::coro_id_retcon_once,
{llvm::ConstantInt::get(
subIGF.IGM.Int32Ty,
getYieldOnceCoroutineBufferSize(subIGF.IGM).getValue()),
llvm::ConstantInt::get(
subIGF.IGM.Int32Ty,
getYieldOnceCoroutineBufferAlignment(subIGF.IGM).getValue()),
buffer, prototype, coroAllocFn, deallocFn, mallocTypeId});
} else {
// Use malloc as our allocator.
auto allocFn = subIGF.IGM.getOpaquePtr(subIGF.IGM.getMallocFn());
id = subIGF.Builder.CreateIntrinsicCall(
llvm::Intrinsic::coro_id_retcon_once,
{llvm::ConstantInt::get(
subIGF.IGM.Int32Ty,
Expand All @@ -1474,6 +1491,7 @@ class CoroPartialApplicationForwarderEmission
subIGF.IGM.Int32Ty,
getYieldOnceCoroutineBufferAlignment(subIGF.IGM).getValue()),
buffer, prototype, allocFn, deallocFn});
}

// Call 'llvm.coro.begin', just for consistency with the normal pattern.
// This serves as a handle that we can pass around to other intrinsics.
Expand Down
4 changes: 4 additions & 0 deletions lib/IRGen/GenPointerAuth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -767,3 +767,7 @@ void ConstantAggregateBuilderBase::addSignedPointer(llvm::Constant *pointer,
addSignedPointer(pointer, schema.getKey(), schema.isAddressDiscriminated(),
llvm::ConstantInt::get(IGM().Int64Ty, otherDiscriminator));
}

llvm::ConstantInt* IRGenFunction::getMallocTypeId() {
return getDiscriminatorForString(IGM, CurFn->getName());
}
2 changes: 2 additions & 0 deletions lib/IRGen/IRGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ class IRGenFunction {
Address getCalleeTypedErrorResultSlot(SILType errorType);
void setCalleeTypedErrorResultSlot(Address addr);

llvm::ConstantInt* getMallocTypeId();

/// Are we currently emitting a coroutine?
bool isCoroutine() {
return CoroutineHandle != nullptr;
Expand Down
4 changes: 2 additions & 2 deletions test/IRGen/yield_once.sil
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ sil @marker : $(Builtin.Int32) -> ()
// CHECK-SAME: [[CORO_ATTRIBUTES:#[0-9]+]]
sil @test_simple : $@yield_once () -> () {
entry:
// CHECK-32: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr %0, ptr @"$sIetA_TC", ptr @malloc, ptr @free)
// CHECK-64: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr %0, ptr @"$sIetA_TC", ptr @malloc, ptr @free)
// CHECK-32: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr %0, ptr @"$sIetA_TC", ptr @malloc, ptr @free)
// CHECK-64: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr %0, ptr @"$sIetA_TC", ptr @malloc, ptr @free)
// CHECK-NEXT: [[BEGIN:%.*]] = call ptr @llvm.coro.begin(token [[ID]], ptr null)

// CHECK-NEXT: call swiftcc void @marker(i32 1000)
Expand Down
8 changes: 4 additions & 4 deletions test/IRGen/yield_once_big.sil
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ entry:
// CHECK-64-SAME: , align 8

// Coroutine setup.
// CHECK-32-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr %0, ptr @"$s14yield_once_big3BigVyxGAA9SomeClassCRbzlIetAYi_TC", ptr @malloc, ptr @free)
// CHECK-64-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr %0, ptr @"$s14yield_once_big3BigVyxGAA9SomeClassCRbzlIetAYi_TC", ptr @malloc, ptr @free)
// CHECK-32-NEXT: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr %0, ptr @"$s14yield_once_big3BigVyxGAA9SomeClassCRbzlIetAYi_TC", ptr @malloc, ptr @free)
// CHECK-64-NEXT: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr %0, ptr @"$s14yield_once_big3BigVyxGAA9SomeClassCRbzlIetAYi_TC", ptr @malloc, ptr @free)
// CHECK-NEXT: [[BEGIN:%.*]] = call ptr @llvm.coro.begin(token [[ID]], ptr null)
// CHECK-NEXT: store ptr

Expand Down Expand Up @@ -181,8 +181,8 @@ entry(%arg : $*BigWrapper<C>):
// CHECK-64-SAME: , align 8

// Coroutine setup.
// CHECK-32-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr %0, ptr @"$s14yield_once_big10BigWrapperVyxGAA0D0VyxGAA9SomeClassCRbzlIetAnYn_TC", ptr @malloc, ptr @free)
// CHECK-64-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr %0, ptr @"$s14yield_once_big10BigWrapperVyxGAA0D0VyxGAA9SomeClassCRbzlIetAnYn_TC", ptr @malloc, ptr @free)
// CHECK-32-NEXT: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr %0, ptr @"$s14yield_once_big10BigWrapperVyxGAA0D0VyxGAA9SomeClassCRbzlIetAnYn_TC", ptr @malloc, ptr @free)
// CHECK-64-NEXT: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr %0, ptr @"$s14yield_once_big10BigWrapperVyxGAA0D0VyxGAA9SomeClassCRbzlIetAnYn_TC", ptr @malloc, ptr @free)
// CHECK-NEXT: [[BEGIN:%.*]] = call ptr @llvm.coro.begin(token [[ID]], ptr null)
// CHECK-NEXT: store ptr

Expand Down
4 changes: 2 additions & 2 deletions test/IRGen/yield_once_biggish.sil
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ entry:
// CHECK-64-SAME: , align 8

// Coroutine setup.
// CHECK-32-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr %0, ptr @"$s18yield_once_biggish7BiggishVyxGAA9SomeClassCRbzlIetAYx_TC", ptr @malloc, ptr @free)
// CHECK-64-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr %0, ptr @"$s18yield_once_biggish7BiggishVyxGAA9SomeClassCRbzlIetAYx_TC", ptr @malloc, ptr @free)
// CHECK-32-NEXT: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr %0, ptr @"$s18yield_once_biggish7BiggishVyxGAA9SomeClassCRbzlIetAYx_TC", ptr @malloc, ptr @free)
// CHECK-64-NEXT: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr %0, ptr @"$s18yield_once_biggish7BiggishVyxGAA9SomeClassCRbzlIetAYx_TC", ptr @malloc, ptr @free)
// CHECK-NEXT: [[BEGIN:%.*]] = call ptr @llvm.coro.begin(token [[ID]], ptr null)
// CHECK-NEXT: store ptr
// CHECK-NEXT: call swiftcc void @marker(i32 1000)
Expand Down
135 changes: 135 additions & 0 deletions test/IRGen/yield_once_enable_emit_type_malloc_coro_frame.sil
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// RUN: %target-swift-frontend -emit-irgen -enable-emit-type-malloc-for-coro-frame %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-ptrsize-%target-ptrauth

import Builtin

sil @marker : $(Builtin.Int32) -> ()

// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc ptr @test_simple
// CHECK-32-SAME: ptr noalias dereferenceable([[BUFFER_SIZE:16]]) %0)
// CHECK-64-SAME: (ptr noalias dereferenceable([[BUFFER_SIZE:32]]) %0)
// CHECK-SAME: [[CORO_ATTRIBUTES:#[0-9]+]]
sil @test_simple : $@yield_once () -> () {
entry:
// CHECK-32: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr %0, ptr @"$sIetA_TC", ptr @swift_coroFrameAlloc, ptr @free, i64 38223)
// CHECK-64: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr %0, ptr @"$sIetA_TC", ptr @swift_coroFrameAlloc, ptr @free, i64 38223)
// CHECK-NEXT: [[BEGIN:%.*]] = call ptr @llvm.coro.begin(token [[ID]], ptr null)

// CHECK-NEXT: call swiftcc void @marker(i32 1000)
%marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
%1000 = integer_literal $Builtin.Int32, 1000
apply %marker(%1000) : $@convention(thin) (Builtin.Int32) -> ()

// CHECK-NEXT: [[IS_UNWIND:%.*]] = call i1 (...) @llvm.coro.suspend.retcon.i1()
// CHECK-NEXT: br i1 [[IS_UNWIND]]
yield (), resume resume, unwind unwind

resume:
// CHECK: call swiftcc void @marker(i32 2000)
%2000 = integer_literal $Builtin.Int32, 2000
apply %marker(%2000) : $@convention(thin) (Builtin.Int32) -> ()
// CHECK: br label %coro.end
%ret = tuple ()
return %ret : $()

unwind:
// CHECK: call swiftcc void @marker(i32 3000)
%3000 = integer_literal $Builtin.Int32, 3000
apply %marker(%3000) : $@convention(thin) (Builtin.Int32) -> ()
// CHECK: br label %coro.end
unwind

// CHECK: coro.end:
// CHECK: call i1 @llvm.coro.end(ptr [[BEGIN]], i1 false, token none)
// CHECK-NEXT: unreachable
}

// CHECK-LABEL: declare{{( dllimport)?}}{{( protected)?}} swiftcc void @"$sIetA_TC"
// CHECK-SAME: (ptr noalias dereferenceable([[BUFFER_SIZE]]), i1)

// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_simple_call(i1 %0)
sil @test_simple_call : $(Builtin.Int1) -> () {
entry(%flag : $Builtin.Int1):
// Allocate the buffer.
// CHECK: [[T0:%.*]] = alloca {{\[}}[[BUFFER_SIZE]] x i8], align [[BUFFER_ALIGN]]
// CHECK-NEXT: [[BUFFER:%.*]] = getelementptr inbounds {{\[}}[[BUFFER_SIZE]] x i8], ptr [[T0]], i32 0, i32 0
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 [[BUFFER_SIZE]], ptr [[BUFFER]])

// Prepare the continuation function pointer to block analysis.
// CHECK-NEXT: [[T0:%.*]] = call ptr @llvm.coro.prepare.retcon(ptr @test_simple)
// Call the function pointer.
// CHECK-NEXT: [[CONTINUATION:%.*]] = call swiftcc ptr [[T0]](ptr noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]])
%0 = function_ref @test_simple : $@convention(thin) @yield_once () -> ()
%token = begin_apply %0() : $@convention(thin) @yield_once () -> ()

// Branch.
// CHECK-NEXT: br i1 %0,
cond_br %flag, yes, no

yes:
// CHECK-64-ptrauth: ptrtoint
// CHECK-64-ptrauth-NEXT: ptrauth.blend
// CHECK: call swiftcc void [[CONTINUATION]](ptr noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false)
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 [[BUFFER_SIZE]], ptr [[BUFFER]])
end_apply %token as $()

// CHECK-NEXT: br label
br cont

no:
// CHECK-64-ptrauth: ptrtoint
// CHECK-64-ptrauth-NEXT: ptrauth.blend
// CHECK: call swiftcc void [[CONTINUATION]](ptr noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 true)
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 [[BUFFER_SIZE]], ptr [[BUFFER]])
abort_apply %token

// CHECK-NEXT: br label
br cont

cont:
// CHECK: ret void
%ret = tuple ()
return %ret : $()
}

sil @yields_pair : $@yield_once @convention(thin) () -> (@yields Builtin.Int32, @yields Builtin.Int32)

// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_yields_pair()
sil @test_yields_pair : $() -> () {
entry:
%marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()

// Allocate the buffer.
// CHECK: [[T0:%.*]] = alloca {{\[}}[[BUFFER_SIZE]] x i8], align [[BUFFER_ALIGN]]
// CHECK-NEXT: [[BUFFER:%.*]] = getelementptr inbounds {{\[}}[[BUFFER_SIZE]] x i8], ptr [[T0]], i32 0, i32 0
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 [[BUFFER_SIZE]], ptr [[BUFFER]])

// Prepare the continuation function pointer to block analysis.
// CHECK-NEXT: [[T0:%.*]] = call ptr @llvm.coro.prepare.retcon(ptr @yields_pair)
// Call the function pointer.
// CHECK-NEXT: [[PACKED:%.*]] = call swiftcc { ptr, i32, i32 } [[T0]](ptr noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]])
// CHECK-NEXT: [[CONTINUATION:%.*]] = extractvalue { ptr, i32, i32 } [[PACKED]], 0
// CHECK-NEXT: [[FIRST:%.*]] = extractvalue { ptr, i32, i32 } [[PACKED]], 1
// CHECK-NEXT: [[SECOND:%.*]] = extractvalue { ptr, i32, i32 } [[PACKED]], 2
%coro = function_ref @yields_pair : $@yield_once @convention(thin) () -> (@yields Builtin.Int32, @yields Builtin.Int32)
(%first, %second, %token) = begin_apply %coro() : $@yield_once @convention(thin) () -> (@yields Builtin.Int32, @yields Builtin.Int32)

// CHECK-NEXT: call swiftcc void @marker(i32 [[FIRST]])
apply %marker(%first) : $@convention(thin) (Builtin.Int32) -> ()

// CHECK-64-ptrauth-NEXT: ptrtoint
// CHECK-64-ptrauth-NEXT: ptrauth.blend
// CHECK-NEXT: call swiftcc void [[CONTINUATION]](ptr noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false)
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 [[BUFFER_SIZE]], ptr [[BUFFER]])
end_apply %token as $()

// CHECK-NEXT: call swiftcc void @marker(i32 [[SECOND]])
apply %marker(%second) : $@convention(thin) (Builtin.Int32) -> ()

// CHECK-NEXT: ret void
%ret = tuple ()
return %ret : $()
}


// CHECK: attributes [[CORO_ATTRIBUTES]] =
// CHECK-SAME: noinline
4 changes: 2 additions & 2 deletions test/IRGen/yield_once_indirect.sil
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ entry:
// CHECK-64-SAME: , align 8

// Coroutine setup.
// CHECK-32-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr %0, ptr @"$s19yield_once_indirect8IndirectVyxGAA9SomeClassCRbzlIetAYi_TC", ptr @malloc, ptr @free)
// CHECK-64-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr %0, ptr @"$s19yield_once_indirect8IndirectVyxGAA9SomeClassCRbzlIetAYi_TC", ptr @malloc, ptr @free)
// CHECK-32-NEXT: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr %0, ptr @"$s19yield_once_indirect8IndirectVyxGAA9SomeClassCRbzlIetAYi_TC", ptr @malloc, ptr @free)
// CHECK-64-NEXT: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr %0, ptr @"$s19yield_once_indirect8IndirectVyxGAA9SomeClassCRbzlIetAYi_TC", ptr @malloc, ptr @free)
// CHECK-NEXT: [[BEGIN:%.*]] = call ptr @llvm.coro.begin(token [[ID]], ptr null)
// CHECK-NEXT: store ptr
// CHECK-NEXT: call swiftcc void @marker(i32 1000)
Expand Down
Loading