xref: /llvm-project/llvm/test/Transforms/Coroutines/coro-split-02.ll (revision 51d5d7bbae92493a5bfa7cc6b519de8a5bb32fdb)
1; Tests that coro-split can handle the case when a code after coro.suspend uses
2; a value produces between coro.save and coro.suspend (%Result.i19)
3; and checks whether stray coro.saves are properly removed
4; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse,simplifycfg' -S | FileCheck %s
5
6%"struct.std::coroutine_handle" = type { ptr }
7%"struct.std::coroutine_handle.0" = type { %"struct.std::coroutine_handle" }
8%"struct.lean_future<int>::Awaiter" = type { i32, %"struct.std::coroutine_handle.0" }
9
10declare ptr @malloc(i64)
11declare void @print(i32)
12
13define void @a() presplitcoroutine {
14entry:
15  %ref.tmp7 = alloca %"struct.lean_future<int>::Awaiter", align 8
16  %testval = alloca i32
17  %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
18  %alloc = call ptr @malloc(i64 16) #3
19  %vFrame = call noalias nonnull ptr @llvm.coro.begin(token %id, ptr %alloc)
20
21  %save = call token @llvm.coro.save(ptr null)
22  %suspend = call i8 @llvm.coro.suspend(token %save, i1 false)
23  switch i8 %suspend, label %exit [
24    i8 0, label %await.ready
25    i8 1, label %exit
26  ]
27await.ready:
28  %StrayCoroSave = call token @llvm.coro.save(ptr null)
29  %val = load i32, ptr %ref.tmp7
30  call void @llvm.lifetime.start.p0(i64 4, ptr %testval)
31  %test = load i32, ptr %testval
32  call void @print(i32 %test)
33  call void @llvm.lifetime.end.p0(i64 4, ptr  %testval)
34  call void @print(i32 %val)
35  br label %exit
36exit:
37  call i1 @llvm.coro.end(ptr null, i1 false, token none)
38  ret void
39}
40
41; CHECK-LABEL: @a.resume(
42; CHECK:         %testval = alloca i32
43; CHECK-NOT:     call token @llvm.coro.save(ptr null)
44; CHECK:         %val = load i32, ptr %ref.tmp7
45; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr %testval)
46; CHECK-NEXT:    %test = load i32, ptr %testval
47; CHECK-NEXT:    call void @print(i32 %test)
48; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr %testval)
49; CHECK-NEXT:    call void @print(i32 %val)
50; CHECK-NEXT:    ret void
51
52declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr)
53declare i1 @llvm.coro.alloc(token) #3
54declare noalias nonnull ptr @"\01??2@YAPEAX_K@Z"(i64) local_unnamed_addr
55declare i64 @llvm.coro.size.i64() #5
56declare ptr @llvm.coro.begin(token, ptr writeonly) #3
57declare void @"\01?puts@@YAXZZ"(...)
58declare token @llvm.coro.save(ptr) #3
59declare ptr @llvm.coro.frame() #5
60declare i8 @llvm.coro.suspend(token, i1) #3
61declare void @"\01??3@YAXPEAX@Z"(ptr) local_unnamed_addr #10
62declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2
63declare i1 @llvm.coro.end(ptr, i1, token) #3
64declare void @llvm.lifetime.start.p0(i64, ptr nocapture) #4
65declare void @llvm.lifetime.end.p0(i64, ptr nocapture) #4
66