blob: 690e01121315c0946f80e57b9349de3faec76570 [file] [log] [blame]
; RUN: opt -passes="cgscc(coro-annotation-elide)" -S < %s | FileCheck %s
%foo.Frame = type { ptr, ptr, i1 }
@foo.resumers = private constant [3 x ptr] [ptr @foo.resume, ptr @foo.destroy, ptr @foo.cleanup]
@foo.resumers.1 = private constant [4 x ptr] [ptr @foo.resume, ptr @foo.destroy, ptr @foo.cleanup, ptr @foo.noalloc]
; CHECK-LABEL: define void @foo
define void @foo(ptr %agg.result, ptr %this) personality ptr null {
entry:
%0 = call token @llvm.coro.id(i32 0, ptr null, ptr nonnull @foo, ptr @foo.resumers.1)
%1 = call noalias nonnull ptr @llvm.coro.begin(token %0, ptr null)
%resume.addr = getelementptr inbounds nuw %foo.Frame, ptr %1, i32 0, i32 0
store ptr @foo.resume, ptr %resume.addr, align 8
%destroy.addr = getelementptr inbounds nuw %foo.Frame, ptr %1, i32 0, i32 1
store ptr @foo.destroy, ptr %destroy.addr, align 8
br label %AllocaSpillBB
AllocaSpillBB: ; preds = %entry
br label %PostSpill
PostSpill: ; preds = %AllocaSpillBB
br label %CoroSave
CoroSave: ; preds = %PostSpill
%index.addr1 = getelementptr inbounds nuw %foo.Frame, ptr %1, i32 0, i32 2
store i1 false, ptr %index.addr1, align 1
br label %CoroSuspend
CoroSuspend: ; preds = %CoroSave
br label %resume.0.landing
resume.0.landing: ; preds = %CoroSuspend
br label %AfterCoroSuspend
AfterCoroSuspend: ; preds = %resume.0.landing
ret void
}
; CHECK-LABEL: define internal void @bar
; Function Attrs: presplitcoroutine
define internal void @bar() #0 personality ptr null {
entry:
; CHECK: %[[CALLEE_FRAME:.+]] = alloca [24 x i8], align 8
%0 = call token @llvm.coro.id(i32 0, ptr null, ptr nonnull @bar, ptr null)
%1 = call i1 @llvm.coro.alloc(token %0)
call void @foo(ptr null, ptr null) #4
; CHECK: %[[FOO_ID:.+]] = call token @llvm.coro.id(i32 0, ptr null, ptr nonnull @foo, ptr @foo.resumers)
; CHECK-NEXT: store ptr @foo.resume, ptr %[[CALLEE_FRAME]], align 8
; CHECK-NEXT: %[[DESTROY_ADDR:.+]] = getelementptr inbounds nuw %foo.Frame, ptr %[[CALLEE_FRAME]], i32 0, i32 1
; CHECK-NEXT: store ptr @foo.destroy, ptr %[[DESTROY_ADDR]], align 8
; CHECK-NEXT: %[[INDEX_ADDR:.+]] = getelementptr inbounds nuw %foo.Frame, ptr %[[CALLEE_FRAME]], i32 0, i32 2
; CHECK-NEXT: store i1 false, ptr %[[INDEX_ADDR]], align 1
; CHECK: ret void
ret void
}
; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: read)
declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1
; Function Attrs: nounwind
declare i1 @llvm.coro.alloc(token) #2
; Function Attrs: nounwind
declare ptr @llvm.coro.begin(token, ptr writeonly) #2
; Function Attrs: nomerge nounwind
declare token @llvm.coro.save(ptr) #3
; Function Attrs: nounwind
declare i8 @llvm.coro.suspend(token, i1) #2
define internal fastcc void @foo.resume(ptr noundef nonnull align 8 dereferenceable(24) %0) personality ptr null {
entry.resume:
br label %resume.entry
resume.0: ; preds = %resume.entry
br label %resume.0.landing
resume.0.landing: ; preds = %resume.0
br label %AfterCoroSuspend
AfterCoroSuspend: ; preds = %resume.0.landing
unreachable
resume.entry: ; preds = %entry.resume
br label %resume.0
}
define internal fastcc void @foo.destroy(ptr noundef nonnull align 8 dereferenceable(24) %0) personality ptr null {
entry.destroy:
br label %resume.entry
resume.0: ; preds = %resume.entry
br label %resume.0.landing
resume.0.landing: ; preds = %resume.0
br label %AfterCoroSuspend
AfterCoroSuspend: ; preds = %resume.0.landing
unreachable
resume.entry: ; preds = %entry.destroy
br label %resume.0
}
define internal fastcc void @foo.cleanup(ptr noundef nonnull align 8 dereferenceable(24) %0) personality ptr null {
entry.cleanup:
br label %resume.entry
resume.0: ; preds = %resume.entry
br label %resume.0.landing
resume.0.landing: ; preds = %resume.0
br label %AfterCoroSuspend
AfterCoroSuspend: ; preds = %resume.0.landing
unreachable
resume.entry: ; preds = %entry.cleanup
br label %resume.0
}
define internal void @foo.noalloc(ptr %0, ptr %1, ptr noundef nonnull align 8 dereferenceable(24) %2) personality ptr null {
entry:
%3 = call token @llvm.coro.id(i32 0, ptr null, ptr nonnull @foo, ptr @foo.resumers)
%resume.addr = getelementptr inbounds nuw %foo.Frame, ptr %2, i32 0, i32 0
store ptr @foo.resume, ptr %resume.addr, align 8
%destroy.addr = getelementptr inbounds nuw %foo.Frame, ptr %2, i32 0, i32 1
store ptr @foo.destroy, ptr %destroy.addr, align 8
br label %AllocaSpillBB
AllocaSpillBB: ; preds = %entry
br label %PostSpill
PostSpill: ; preds = %AllocaSpillBB
br label %CoroSave
CoroSave: ; preds = %PostSpill
%index.addr1 = getelementptr inbounds nuw %foo.Frame, ptr %2, i32 0, i32 2
store i1 false, ptr %index.addr1, align 1
br label %CoroSuspend
CoroSuspend: ; preds = %CoroSave
br label %resume.0.landing
resume.0.landing: ; preds = %CoroSuspend
br label %AfterCoroSuspend
AfterCoroSuspend: ; preds = %resume.0.landing
ret void
}
attributes #0 = { presplitcoroutine }
attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: read) }
attributes #2 = { nounwind }
attributes #3 = { nomerge nounwind }
attributes #4 = { coro_elide_safe }