1 ; Tests that the coro.destroy and coro.resume are devirtualized where possible,
2 ; SCC pipeline restarts and inlines the direct calls.
4 ; RUN: -passes='cgscc(repeat<2>(inline,function(coro-elide,dce)))' \
7 declare void @print(i32) nounwind
9 ; resume part of the coroutine
10 define fastcc void @f.resume(i8*) {
11 tail call void @print(i32 0)
15 ; destroy part of the coroutine
16 define fastcc void @f.destroy(i8*) {
17 tail call void @print(i32 1)
21 ; cleanup part of the coroutine
22 define fastcc void @f.cleanup(i8*) {
23 tail call void @print(i32 2)
27 @f.resumers = internal constant [3 x void (i8*)*] [void (i8*)* @f.resume,
28 void (i8*)* @f.destroy,
29 void (i8*)* @f.cleanup]
31 ; a coroutine start function
34 %id = call token @llvm.coro.id(i32 0, i8* null,
35 i8* bitcast (i8*()* @f to i8*),
36 i8* bitcast ([3 x void (i8*)*]* @f.resumers to i8*))
37 %alloc = call i1 @llvm.coro.alloc(token %id)
38 %hdl = call i8* @llvm.coro.begin(token %id, i8* null)
42 ; CHECK-LABEL: @callResume(
43 define void @callResume() {
47 ; CHECK: call void @print(i32 0)
48 %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
49 %1 = bitcast i8* %0 to void (i8*)*
50 call fastcc void %1(i8* %hdl)
52 ; CHECK-NEXT: call void @print(i32 2)
53 %2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
54 %3 = bitcast i8* %2 to void (i8*)*
55 call fastcc void %3(i8* %hdl)
57 ; CHECK-NEXT: ret void
61 ; CHECK-LABEL: @callResumeMultiRet(
62 define void @callResumeMultiRet(i1 %b) {
65 ; CHECK: %alloc.i = call i1 @llvm.coro.alloc
66 ; CHECK: call void @print(i32 0)
67 %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
68 %1 = bitcast i8* %0 to void (i8*)*
69 call fastcc void %1(i8* %hdl)
70 br i1 %b, label %destroy, label %ret
73 ; CHECK: call void @print(i32 1)
74 %2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
75 %3 = bitcast i8* %2 to void (i8*)*
76 call fastcc void %3(i8* %hdl)
83 ; CHECK-LABEL: @callResumeMultiRetDommmed(
84 define void @callResumeMultiRetDommmed(i1 %b) {
87 ; CHECK-NOT: %alloc.i = call i1 @llvm.coro.alloc
88 ; CHECK: call void @print(i32 0)
89 %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
90 %1 = bitcast i8* %0 to void (i8*)*
91 call fastcc void %1(i8* %hdl)
92 ; CHECK: call void @print(i32 2)
93 %2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
94 %3 = bitcast i8* %2 to void (i8*)*
95 call fastcc void %3(i8* %hdl)
96 br i1 %b, label %destroy, label %ret
106 define void @eh() personality i8* null {
110 ; CHECK: call void @print(i32 0)
111 %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
112 %1 = bitcast i8* %0 to void (i8*)*
113 invoke void %1(i8* %hdl)
114 to label %cont unwind label %ehcleanup
119 %tok = cleanuppad within none []
120 cleanupret from %tok unwind to caller
123 ; CHECK-LABEL: @no_devirt_info_null(
124 ; no devirtualization here, since coro.begin info parameter is null
125 define void @no_devirt_info_null() {
127 %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
128 %hdl = call i8* @llvm.coro.begin(token %id, i8* null)
130 ; CHECK: call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
131 %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
132 %1 = bitcast i8* %0 to void (i8*)*
133 call fastcc void %1(i8* %hdl)
135 ; CHECK: call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
136 %2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
137 %3 = bitcast i8* %2 to void (i8*)*
138 call fastcc void %3(i8* %hdl)
144 ; CHECK-LABEL: @no_devirt_no_begin(
145 ; no devirtualization here, since coro.begin is not visible
146 define void @no_devirt_no_begin(i8* %hdl) {
149 ; CHECK: call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
150 %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
151 %1 = bitcast i8* %0 to void (i8*)*
152 call fastcc void %1(i8* %hdl)
154 ; CHECK: call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
155 %2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
156 %3 = bitcast i8* %2 to void (i8*)*
157 call fastcc void %3(i8* %hdl)
163 declare token @llvm.coro.id(i32, i8*, i8*, i8*)
164 declare i8* @llvm.coro.begin(token, i8*)
165 declare i8* @llvm.coro.frame()
166 declare i8* @llvm.coro.subfn.addr(i8*, i8)
167 declare i1 @llvm.coro.alloc(token)