1
1
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2
2
; First example from Doc/Coroutines.rst (two block loop) converted to retcon
3
3
; RUN: opt < %s -passes='default<O2>' -S | FileCheck %s
4
+ ; RUN: opt < %s -passes='module(coro-early),cgscc(coro-split),module(coro-cleanup)' -S | FileCheck --check-prefix=CORO %s
4
5
5
6
define i8* @f (i8* %buffer , i32 %n ) {
6
7
; CHECK-LABEL: @f(
@@ -10,6 +11,15 @@ define i8* @f(i8* %buffer, i32 %n) {
10
11
; CHECK-NEXT: tail call void @print(i32 [[N]])
11
12
; CHECK-NEXT: ret i8* bitcast (i8* (i8*, i1)* @f.resume.0 to i8*)
12
13
;
14
+ ; CORO-LABEL: @f(
15
+ ; CORO-NEXT: entry:
16
+ ; CORO-NEXT: [[FRAMEPTR:%.*]] = bitcast i8* [[BUFFER:%.*]] to %f.Frame*
17
+ ; CORO-NEXT: [[N_VAL_SPILL_ADDR:%.*]] = getelementptr inbounds [[F_FRAME:%.*]], %f.Frame* [[FRAMEPTR]], i32 0, i32 0
18
+ ; CORO-NEXT: store i32 [[N:%.*]], i32* [[N_VAL_SPILL_ADDR]], align 4
19
+ ; CORO-NEXT: call void @print(i32 [[N]])
20
+ ; CORO-NEXT: [[TMP0:%.*]] = bitcast i8* (i8*, i1)* @f.resume.0 to i8*
21
+ ; CORO-NEXT: ret i8* [[TMP0]]
22
+ ;
13
23
entry:
14
24
%id = call token @llvm.coro.id.retcon (i32 8 , i32 4 , i8* %buffer , i8* bitcast (i8* (i8* , i1 )* @prototype to i8* ), i8* bitcast (i8* (i32 )* @allocate to i8* ), i8* bitcast (void (i8* )* @deallocate to i8* ))
15
25
%hdl = call i8* @llvm.coro.begin (token %id , i8* null )
@@ -35,11 +45,24 @@ cleanup:
35
45
define i32 @main () {
36
46
; CHECK-LABEL: @main(
37
47
; CHECK-NEXT: entry:
38
- ; CHECK-NEXT: call void @print(i32 4)
39
- ; CHECK-NEXT: call void @print(i32 5), !noalias !0
40
- ; CHECK-NEXT: call void @print(i32 6), !noalias !3
48
+ ; CHECK-NEXT: tail call void @print(i32 4)
49
+ ; CHECK-NEXT: tail call void @print(i32 5), !noalias !0
50
+ ; CHECK-NEXT: tail call void @print(i32 6), !noalias !3
41
51
; CHECK-NEXT: ret i32 0
42
52
;
53
+ ; CORO-LABEL: @main(
54
+ ; CORO-NEXT: entry:
55
+ ; CORO-NEXT: [[TMP0:%.*]] = alloca [8 x i8], align 4
56
+ ; CORO-NEXT: [[BUFFER:%.*]] = bitcast [8 x i8]* [[TMP0]] to i8*
57
+ ; CORO-NEXT: [[CONT0:%.*]] = call i8* @f(i8* [[BUFFER]], i32 4)
58
+ ; CORO-NEXT: [[CONT0_CAST:%.*]] = bitcast i8* [[CONT0]] to i8* (i8*, i1)*
59
+ ; CORO-NEXT: [[CONT1:%.*]] = call i8* [[CONT0_CAST]](i8* [[BUFFER]], i1 zeroext false)
60
+ ; CORO-NEXT: [[CONT1_CAST:%.*]] = bitcast i8* [[CONT1]] to i8* (i8*, i1)*
61
+ ; CORO-NEXT: [[CONT2:%.*]] = call i8* [[CONT1_CAST]](i8* [[BUFFER]], i1 zeroext false)
62
+ ; CORO-NEXT: [[CONT2_CAST:%.*]] = bitcast i8* [[CONT2]] to i8* (i8*, i1)*
63
+ ; CORO-NEXT: [[TMP1:%.*]] = call i8* [[CONT2_CAST]](i8* [[BUFFER]], i1 zeroext true)
64
+ ; CORO-NEXT: ret i32 0
65
+ ;
43
66
entry:
44
67
%0 = alloca [8 x i8 ], align 4
45
68
%buffer = bitcast [8 x i8 ]* %0 to i8*
@@ -70,6 +93,22 @@ define hidden { i8*, i8* } @g(i8* %buffer, i16* %ptr) {
70
93
; CHECK-NEXT: [[TMP3:%.*]] = insertvalue { i8*, i8* } { i8* bitcast ({ i8*, i8* } (i8*, i1)* @g.resume.0 to i8*), i8* undef }, i8* [[TMP2]], 1
71
94
; CHECK-NEXT: ret { i8*, i8* } [[TMP3]]
72
95
;
96
+ ; CORO-LABEL: @g(
97
+ ; CORO-NEXT: entry:
98
+ ; CORO-NEXT: [[TMP0:%.*]] = call i8* @allocate(i32 8)
99
+ ; CORO-NEXT: [[TMP1:%.*]] = bitcast i8* [[BUFFER:%.*]] to i8**
100
+ ; CORO-NEXT: store i8* [[TMP0]], i8** [[TMP1]], align 8
101
+ ; CORO-NEXT: [[FRAMEPTR:%.*]] = bitcast i8* [[TMP0]] to %g.Frame*
102
+ ; CORO-NEXT: [[PTR_SPILL_ADDR:%.*]] = getelementptr inbounds [[G_FRAME:%.*]], %g.Frame* [[FRAMEPTR]], i32 0, i32 0
103
+ ; CORO-NEXT: store i16* [[PTR:%.*]], i16** [[PTR_SPILL_ADDR]], align 8
104
+ ; CORO-NEXT: [[PTR_RELOAD_ADDR:%.*]] = getelementptr inbounds [[G_FRAME]], %g.Frame* [[FRAMEPTR]], i32 0, i32 0
105
+ ; CORO-NEXT: [[PTR_RELOAD:%.*]] = load i16*, i16** [[PTR_RELOAD_ADDR]], align 8
106
+ ; CORO-NEXT: [[PTR2:%.*]] = bitcast i16* [[PTR_RELOAD]] to i8*
107
+ ; CORO-NEXT: [[TMP2:%.*]] = bitcast { i8*, i8* } (i8*, i1)* @g.resume.0 to i8*
108
+ ; CORO-NEXT: [[TMP3:%.*]] = insertvalue { i8*, i8* } undef, i8* [[TMP2]], 0
109
+ ; CORO-NEXT: [[TMP4:%.*]] = insertvalue { i8*, i8* } [[TMP3]], i8* [[PTR2]], 1
110
+ ; CORO-NEXT: ret { i8*, i8* } [[TMP4]]
111
+ ;
73
112
entry:
74
113
%id = call token @llvm.coro.id.retcon (i32 8 , i32 4 , i8* %buffer , i8* bitcast ({ i8* , i8* } (i8* , i1 )* @g_prototype to i8* ), i8* bitcast (i8* (i32 )* @allocate to i8* ), i8* bitcast (void (i8* )* @deallocate to i8* ))
75
114
%hdl = call i8* @llvm.coro.begin (token %id , i8* null )
@@ -88,12 +127,45 @@ cleanup:
88
127
unreachable
89
128
}
90
129
130
+ define i8* @nosuspend (i8* %buffer , i32 %n ) {
131
+ ; CHECK-LABEL: @nosuspend(
132
+ ; CHECK-NEXT: entry:
133
+ ; CHECK-NEXT: unreachable
134
+ ;
135
+ ; CORO-LABEL: @nosuspend(
136
+ ; CORO-NEXT: entry:
137
+ ; CORO-NEXT: [[FRAMEPTR:%.*]] = bitcast i8* undef to %nosuspend.Frame*
138
+ ; CORO-NEXT: [[A:%.*]] = getelementptr inbounds [[NOSUSPEND_FRAME:%.*]], %nosuspend.Frame* [[FRAMEPTR]], i32 0, i32 0
139
+ ; CORO-NEXT: store i32 [[N:%.*]], i32* [[A]], align 4
140
+ ; CORO-NEXT: call void @use_var_ptr(i32* [[A]])
141
+ ; CORO-NEXT: [[AL:%.*]] = load i32, i32* [[A]], align 4
142
+ ; CORO-NEXT: call void @use_var(i32 [[AL]])
143
+ ; CORO-NEXT: ret i8* null
144
+ ;
145
+ entry:
146
+ %id = call token @llvm.coro.id.retcon (i32 8 , i32 4 , i8* %buffer , i8* bitcast (i8* (i8* , i1 )* @prototype to i8* ), i8* bitcast (i8* (i32 )* @allocate to i8* ), i8* bitcast (void (i8* )* @deallocate to i8* ))
147
+ %hdl = call i8* @llvm.coro.begin (token %id , i8* null )
148
+ %a = alloca i32
149
+ store i32 %n , i32* %a
150
+ br label %cleanup
151
+
152
+ cleanup:
153
+ call void @use_var_ptr (i32* %a )
154
+ %al = load i32 , i32* %a
155
+ call void @use_var (i32 %al )
156
+ call i1 @llvm.coro.end (i8* %hdl , i1 0 )
157
+ ret i8* %hdl
158
+ }
159
+
91
160
declare token @llvm.coro.id.retcon (i32 , i32 , i8* , i8* , i8* , i8* )
92
161
declare i8* @llvm.coro.begin (token, i8* )
93
162
declare i1 @llvm.coro.suspend.retcon.i1 (...)
94
163
declare i1 @llvm.coro.end (i8* , i1 )
95
164
declare i8* @llvm.coro.prepare.retcon (i8* )
96
165
166
+ declare void @use_var (i32 )
167
+ declare void @use_var_ptr (i32* )
168
+
97
169
declare i8* @prototype (i8* , i1 zeroext )
98
170
declare {i8* ,i8* } @g_prototype (i8* , i1 zeroext )
99
171
0 commit comments