Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / Coroutines / coro-only-destroy-when-complete.ll
blob3f0899a02178e31ec390eace5f9ff418d1bf0558
1 ; RUN: opt < %s -passes='cgscc(coro-split),early-cse,dce,simplifycfg' -S | FileCheck %s
3 %"struct.std::__n4861::noop_coroutine_promise" = type { i8 }
4 %struct.Promise = type { %"struct.std::__n4861::coroutine_handle" }
5 %"struct.std::__n4861::coroutine_handle" = type { ptr }
7 define ptr @foo() #1 {
8 entry:
9   %__promise = alloca %struct.Promise, align 8
10   %0 = call token @llvm.coro.id(i32 16, ptr nonnull %__promise, ptr nonnull @foo, ptr null)
11   %1 = call i1 @llvm.coro.alloc(token %0)
12   br i1 %1, label %coro.alloc, label %init.suspend
14 coro.alloc:                                       ; preds = %entry
15   %2 = tail call i64 @llvm.coro.size.i64()
16   %call = call noalias noundef nonnull ptr @_Znwm(i64 noundef %2) #11
17   br label %init.suspend
19 init.suspend:                                     ; preds = %entry, %coro.alloc
20   %3 = phi ptr [ null, %entry ], [ %call, %coro.alloc ]
21   %4 = call ptr @llvm.coro.begin(token %0, ptr %3) #12
22   call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %__promise) #3
23   store ptr null, ptr %__promise, align 8
24   %5 = call token @llvm.coro.save(ptr null)
25   %6 = call i8 @llvm.coro.suspend(token %5, i1 false)
26   switch i8 %6, label %coro.ret [
27   i8 0, label %await.suspend
28   i8 1, label %cleanup1
29   ]
31 await.suspend:                                    ; preds = %init.suspend
32   %7 = call token @llvm.coro.save(ptr null)
33   %8 = call i8 @llvm.coro.suspend(token %7, i1 false)
34   switch i8 %8, label %coro.ret [
35   i8 0, label %await2.suspend
36   i8 1, label %cleanup2
37   ]
39 await2.suspend:                                   ; preds = %await.suspend
40   %call27 = call ptr @_Z5Innerv() #3
41   %9 = call token @llvm.coro.save(ptr null)
42   %10 = getelementptr inbounds i8, ptr %__promise, i64 -16
43   store ptr %10, ptr %call27, align 8
44   %11 = getelementptr inbounds i8, ptr %call27, i64 -16
45   %12 = call ptr @llvm.coro.subfn.addr(ptr nonnull %11, i8 0)
46   call fastcc void %12(ptr nonnull %11) #3
47   %13 = call i8 @llvm.coro.suspend(token %9, i1 false)
48   switch i8 %13, label %coro.ret [
49   i8 0, label %final.suspend
50   i8 1, label %cleanup3
51   ]
53 final.suspend:                                    ; preds = %await2.suspend
54   %14 = call ptr @llvm.coro.subfn.addr(ptr nonnull %11, i8 1)
55   call fastcc void %14(ptr nonnull %11) #3
56   %15 = call token @llvm.coro.save(ptr null)
57   %retval.sroa.0.0.copyload.i = load ptr, ptr %__promise, align 8
58   %16 = call ptr @llvm.coro.subfn.addr(ptr %retval.sroa.0.0.copyload.i, i8 0)
59   call fastcc void %16(ptr %retval.sroa.0.0.copyload.i) #3
60   %17 = call i8 @llvm.coro.suspend(token %15, i1 true) #12
61   switch i8 %17, label %coro.ret [
62   i8 0, label %final.ready
63   i8 1, label %cleanup62
64   ]
66 final.ready:                                      ; preds = %final.suspend
67   call void @exit(i32 noundef 1)
68   unreachable
70 cleanup1:
71   call void @dtor1()
72   br label %cleanup62
74 cleanup2:
75   call void @dtor2()
76   br label %cleanup62
78 cleanup3:
79   call void @dtor3()
80   br label %cleanup62
82 cleanup62:                                        ; preds = %await2.suspend, %await.suspend, %init.suspend, %final.suspend
83   call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %__promise) #3
84   %18 = call ptr @llvm.coro.free(token %0, ptr %4)
85   %.not = icmp eq ptr %18, null
86   br i1 %.not, label %coro.ret, label %coro.free
88 coro.free:                                        ; preds = %cleanup62
89   call void @_ZdlPv(ptr noundef nonnull %18) #3
90   br label %coro.ret
92 coro.ret:                                         ; preds = %coro.free, %cleanup62, %final.suspend, %await2.suspend, %await.suspend, %init.suspend
93   %19 = call i1 @llvm.coro.end(ptr null, i1 false, token none) #12
94   ret ptr %__promise
97 declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #2
98 declare i1 @llvm.coro.alloc(token) #3
99 declare dso_local noundef nonnull ptr @_Znwm(i64 noundef) local_unnamed_addr #4
100 declare i64 @llvm.coro.size.i64() #5
101 declare ptr @llvm.coro.begin(token, ptr writeonly) #3
102 declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #6
103 declare token @llvm.coro.save(ptr) #7
104 declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #6
105 declare i8 @llvm.coro.suspend(token, i1) #3
106 declare ptr @_Z5Innerv() local_unnamed_addr
107 declare dso_local void @_ZdlPv(ptr noundef) local_unnamed_addr #8
108 declare ptr @llvm.coro.free(token, ptr nocapture readonly) #2
109 declare i1 @llvm.coro.end(ptr, i1, token) #3
110 declare void @exit(i32 noundef)
111 declare ptr @llvm.coro.subfn.addr(ptr nocapture readonly, i8) #10
112 declare void @dtor1()
113 declare void @dtor2()
114 declare void @dtor3()
116 attributes #0 = { mustprogress nounwind uwtable }
117 attributes #1 = { nounwind presplitcoroutine uwtable coro_only_destroy_when_complete }
118 attributes #2 = { argmemonly nofree nounwind readonly }
119 attributes #3 = { nounwind }
120 attributes #4 = { nobuiltin allocsize(0) }
121 attributes #5 = { nofree nosync nounwind readnone }
122 attributes #6 = { argmemonly mustprogress nocallback nofree nosync nounwind willreturn }
123 attributes #7 = { nomerge nounwind }
124 attributes #8 = { nobuiltin nounwind }
125 attributes #9 = { noreturn }
126 attributes #10 = { argmemonly nounwind readonly }
127 attributes #11 = { nounwind allocsize(0) }
128 attributes #12 = { noduplicate }
130 ; CHECK: define{{.*}}@foo.destroy(
131 ; CHECK-NEXT: entry.destroy:
132 ; CHECK-NEXT: call void @_ZdlPv
133 ; CHECK-NEXT: ret void
135 ; CHECK: define{{.*}}@foo.cleanup(
136 ; CHECK-NEXT: entry.cleanup:
137 ; CHECK-NEXT: ret void