]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/Transforms/Coroutines/coro-elide.ll
Vendor import of llvm trunk r291012:
[FreeBSD/FreeBSD.git] / test / Transforms / Coroutines / coro-elide.ll
1 ; Tests that the coro.destroy and coro.resume are devirtualized where possible,
2 ; SCC pipeline restarts and inlines the direct calls.
3 ; RUN: opt < %s -S -inline -coro-elide -dce | FileCheck %s
4
5 declare void @print(i32) nounwind
6
7 ; resume part of the coroutine
8 define fastcc void @f.resume(i8*) {
9   tail call void @print(i32 0)
10   ret void
11 }
12
13 ; destroy part of the coroutine
14 define fastcc void @f.destroy(i8*) {
15   tail call void @print(i32 1)
16   ret void
17 }
18
19 @f.resumers = internal constant [2 x void (i8*)*] [void (i8*)* @f.resume,
20                                                    void (i8*)* @f.destroy]
21
22 ; a coroutine start function
23 define i8* @f() {
24 entry:
25   %id = call token @llvm.coro.id(i32 0, i8* null,
26                           i8* bitcast (i8*()* @f to i8*),
27                           i8* bitcast ([2 x void (i8*)*]* @f.resumers to i8*))
28   %hdl = call i8* @llvm.coro.begin(token %id, i8* null)
29   ret i8* %hdl
30 }
31
32 ; CHECK-LABEL: @callResume(
33 define void @callResume() {
34 entry:
35   %hdl = call i8* @f()
36
37 ; CHECK: call void @print(i32 0)
38   %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
39   %1 = bitcast i8* %0 to void (i8*)*
40   call fastcc void %1(i8* %hdl)
41
42 ; CHECK-NEXT: call void @print(i32 1)
43   %2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
44   %3 = bitcast i8* %2 to void (i8*)*
45   call fastcc void %3(i8* %hdl)
46
47 ; CHECK-NEXT: ret void
48   ret void
49 }
50
51 ; CHECK-LABEL: @eh(
52 define void @eh() personality i8* null {
53 entry:
54   %hdl = call i8* @f()
55
56 ; CHECK: call void @print(i32 0)
57   %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
58   %1 = bitcast i8* %0 to void (i8*)*
59   invoke void %1(i8* %hdl)
60           to label %cont unwind label %ehcleanup
61 cont:
62   ret void
63
64 ehcleanup:
65   %tok = cleanuppad within none []
66   cleanupret from %tok unwind to caller
67 }
68
69 ; CHECK-LABEL: @no_devirt_info_null(
70 ; no devirtualization here, since coro.begin info parameter is null
71 define void @no_devirt_info_null() {
72 entry:
73   %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
74   %hdl = call i8* @llvm.coro.begin(token %id, i8* null)
75
76 ; CHECK: call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
77   %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
78   %1 = bitcast i8* %0 to void (i8*)*
79   call fastcc void %1(i8* %hdl)
80
81 ; CHECK: call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
82   %2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
83   %3 = bitcast i8* %2 to void (i8*)*
84   call fastcc void %3(i8* %hdl)
85
86 ; CHECK: ret void
87   ret void
88 }
89
90 ; CHECK-LABEL: @no_devirt_no_begin(
91 ; no devirtualization here, since coro.begin is not visible
92 define void @no_devirt_no_begin(i8* %hdl) {
93 entry:
94
95 ; CHECK: call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
96   %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0)
97   %1 = bitcast i8* %0 to void (i8*)*
98   call fastcc void %1(i8* %hdl)
99
100 ; CHECK: call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
101   %2 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 1)
102   %3 = bitcast i8* %2 to void (i8*)*
103   call fastcc void %3(i8* %hdl)
104
105 ; CHECK: ret void
106   ret void
107 }
108
109 declare token @llvm.coro.id(i32, i8*, i8*, i8*)
110 declare i8* @llvm.coro.begin(token, i8*)
111 declare i8* @llvm.coro.frame()
112 declare i8* @llvm.coro.subfn.addr(i8*, i8)