Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / Coroutines / coro-materialize.ll
blob8de81c3b8cfd3ebcb0488d7136a589740ea4ebbe
1 ; Verifies that we materialize instruction across suspend points
2 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -S | FileCheck %s
4 ; See that we only spilled one value for f
5 ; CHECK: %f.Frame = type { ptr, ptr, i32, i1 }
6 ; CHECK: %f_optnone.Frame = type { ptr, ptr, i32, i32, i1 }
7 ; Check other variants where different levels of materialization are achieved
8 ; CHECK: %f_multiple_remat.Frame = type { ptr, ptr, i32, i1 }
9 ; CHECK: %f_common_def.Frame = type { ptr, ptr, i32, i1 }
10 ; CHECK: %f_common_def_multi_result.Frame = type { ptr, ptr, i32, i1 }
11 ; CHECK-LABEL: @f(
12 ; CHECK-LABEL: @f_optnone
13 ; CHECK-LABEL: @f_multiple_remat(
14 ; CHECK-LABEL: @f_common_def(
15 ; CHECK-LABEL: @f_common_def_multi_result(
17 define ptr @f(i32 %n) presplitcoroutine {
18 entry:
19   %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
20   %size = call i32 @llvm.coro.size.i32()
21   %alloc = call ptr @malloc(i32 %size)
22   %hdl = call ptr @llvm.coro.begin(token %id, ptr %alloc)
24   %inc1 = add i32 %n, 1
25   %sp1 = call i8 @llvm.coro.suspend(token none, i1 false)
26   switch i8 %sp1, label %suspend [i8 0, label %resume1
27                                   i8 1, label %cleanup]
28 resume1:
29   %inc2 = add i32 %inc1, 1
30   %sp2 = call i8 @llvm.coro.suspend(token none, i1 false)
31   switch i8 %sp1, label %suspend [i8 0, label %resume2
32                                   i8 1, label %cleanup]
34 resume2:
35   call void @print(i32 %inc1)
36   call void @print(i32 %inc2)
37   br label %cleanup
39 cleanup:
40   %mem = call ptr @llvm.coro.free(token %id, ptr %hdl)
41   call void @free(ptr %mem)
42   br label %suspend
43 suspend:
44   call i1 @llvm.coro.end(ptr %hdl, i1 0, token none)
45   ret ptr %hdl
48 ; Checks that we won't transform functions with optnone.
49 define ptr @f_optnone(i32 %n) presplitcoroutine optnone noinline {
50 entry:
51   %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
52   %size = call i32 @llvm.coro.size.i32()
53   %alloc = call ptr @malloc(i32 %size)
54   %hdl = call ptr @llvm.coro.begin(token %id, ptr %alloc)
56   %inc1 = add i32 %n, 1
57   %sp1 = call i8 @llvm.coro.suspend(token none, i1 false)
58   switch i8 %sp1, label %suspend [i8 0, label %resume1
59                                   i8 1, label %cleanup]
60 resume1:
61   %inc2 = add i32 %inc1, 1
62   %sp2 = call i8 @llvm.coro.suspend(token none, i1 false)
63   switch i8 %sp1, label %suspend [i8 0, label %resume2
64                                   i8 1, label %cleanup]
66 resume2:
67   call void @print(i32 %inc1)
68   call void @print(i32 %inc2)
69   br label %cleanup
71 cleanup:
72   %mem = call ptr @llvm.coro.free(token %id, ptr %hdl)
73   call void @free(ptr %mem)
74   br label %suspend
75 suspend:
76   call i1 @llvm.coro.end(ptr %hdl, i1 0, token none)
77   ret ptr %hdl
80 define ptr @f_multiple_remat(i32 %n) presplitcoroutine {
81 entry:
82   %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
83   %size = call i32 @llvm.coro.size.i32()
84   %alloc = call ptr @malloc(i32 %size)
85   %hdl = call ptr @llvm.coro.begin(token %id, ptr %alloc)
87   %inc1 = add i32 %n, 1
88   %inc2 = add i32 %inc1, 2
89   %inc3 = add i32 %inc2, 3
90   %inc4 = add i32 %inc3, 4
91   %inc5 = add i32 %inc4, 5
92   %inc6 = add i32 %inc5, 5
93   %sp1 = call i8 @llvm.coro.suspend(token none, i1 false)
94   switch i8 %sp1, label %suspend [i8 0, label %resume1
95                                   i8 1, label %cleanup]
96 resume1:
97   %inc7 = add i32 %inc6, 1
98   %sp2 = call i8 @llvm.coro.suspend(token none, i1 false)
99   switch i8 %sp1, label %suspend [i8 0, label %resume2
100                                   i8 1, label %cleanup]
102 resume2:
103   call void @print(i32 %inc1)
104   call void @print(i32 %inc7)
105   br label %cleanup
107 cleanup:
108   %mem = call ptr @llvm.coro.free(token %id, ptr %hdl)
109   call void @free(ptr %mem)
110   br label %suspend
111 suspend:
112   call i1 @llvm.coro.end(ptr %hdl, i1 0, token none)
113   ret ptr %hdl
116 define ptr @f_common_def(i32 %n) presplitcoroutine {
117 entry:
118   %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
119   %size = call i32 @llvm.coro.size.i32()
120   %alloc = call ptr @malloc(i32 %size)
121   %hdl = call ptr @llvm.coro.begin(token %id, ptr %alloc)
123   %inc1 = add i32 %n, 1
124   %inc2 = add i32 %inc1, 2
125   %inc3 = add i32 %n, 3
126   %inc4 = add i32 %inc3, %inc1
127   %inc5 = add i32 %inc4, %inc1
128   %inc6 = add i32 %inc5, 5
129   %sp1 = call i8 @llvm.coro.suspend(token none, i1 false)
130   switch i8 %sp1, label %suspend [i8 0, label %resume1
131                                   i8 1, label %cleanup]
132 resume1:
133   %inc7 = add i32 %inc6, 1
134   %sp2 = call i8 @llvm.coro.suspend(token none, i1 false)
135   switch i8 %sp1, label %suspend [i8 0, label %resume2
136                                   i8 1, label %cleanup]
138 resume2:
139   call void @print(i32 %inc1)
140   call void @print(i32 %inc7)
141   br label %cleanup
143 cleanup:
144   %mem = call ptr @llvm.coro.free(token %id, ptr %hdl)
145   call void @free(ptr %mem)
146   br label %suspend
147 suspend:
148   call i1 @llvm.coro.end(ptr %hdl, i1 0, token none)
149   ret ptr %hdl
152 define ptr @f_common_def_multi_result(i32 %n) presplitcoroutine {
153 entry:
154   %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
155   %size = call i32 @llvm.coro.size.i32()
156   %alloc = call ptr @malloc(i32 %size)
157   %hdl = call ptr @llvm.coro.begin(token %id, ptr %alloc)
159   %inc1 = add i32 %n, 1
160   %inc2 = add i32 %inc1, 2
161   %inc3 = add i32 %n, 3
162   %inc4 = add i32 %inc3, %inc1
163   %inc5 = add i32 %inc4, %inc1
164   %inc6 = add i32 %inc5, 4
165   %inc7 = add i32 %inc6, 5
166   %inc8 = add i32 %inc4, %inc2
167   %inc9 = add i32 %inc8, 5
168   %inc10 = add i32 %inc9, 6
169   %inc11 = add i32 %inc10, 7
170   %sp1 = call i8 @llvm.coro.suspend(token none, i1 false)
171   switch i8 %sp1, label %suspend [i8 0, label %resume1
172                                   i8 1, label %cleanup]
173 resume1:
174   %inc12 = add i32 %inc7, 1
175   %sp2 = call i8 @llvm.coro.suspend(token none, i1 false)
176   switch i8 %sp1, label %suspend [i8 0, label %resume2
177                                   i8 1, label %cleanup]
179 resume2:
180   call void @print(i32 %inc11)
181   call void @print(i32 %inc12)
182   br label %cleanup
184 cleanup:
185   %mem = call ptr @llvm.coro.free(token %id, ptr %hdl)
186   call void @free(ptr %mem)
187   br label %suspend
188 suspend:
189   call i1 @llvm.coro.end(ptr %hdl, i1 0, token none)
190   ret ptr %hdl
194 declare ptr @llvm.coro.free(token, ptr)
195 declare i32 @llvm.coro.size.i32()
196 declare i8  @llvm.coro.suspend(token, i1)
197 declare void @llvm.coro.resume(ptr)
198 declare void @llvm.coro.destroy(ptr)
200 declare token @llvm.coro.id(i32, ptr, ptr, ptr)
201 declare i1 @llvm.coro.alloc(token)
202 declare ptr @llvm.coro.begin(token, ptr)
203 declare i1 @llvm.coro.end(ptr, i1, token)
205 declare noalias ptr @malloc(i32)
206 declare void @print(i32)
207 declare void @free(ptr)