summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorGor Nishanov <GorNishanov@gmail.com>2016-09-30 19:24:19 +0000
committerGor Nishanov <GorNishanov@gmail.com>2016-09-30 19:24:19 +0000
commita263a60ad5c6b299c23c86c440c69a3ff98bbcd5 (patch)
treef434234b39f2d6dcfb683b797699f9af7149fdba /llvm/test
parent75b25187627bbf78453f2cefb24fa28a07ceb289 (diff)
downloadbcm5719-llvm-a263a60ad5c6b299c23c86c440c69a3ff98bbcd5.tar.gz
bcm5719-llvm-a263a60ad5c6b299c23c86c440c69a3ff98bbcd5.zip
[Coroutines] Part15c: Fix coro-split to correctly handle definitions between coro.save and coro.suspend
Summary: In the case below, %Result.i19 is defined between coro.save and coro.suspend and used after coro.suspend. We need to correctly place such a value into the coroutine frame. ``` %save = call token @llvm.coro.save(i8* null) %Result.i19 = getelementptr inbounds %"struct.lean_future<int>::Awaiter", %"struct.lean_future<int>::Awaiter"* %ref.tmp7, i64 0, i32 0 %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) switch i8 %suspend, label %exit [ i8 0, label %await.ready i8 1, label %exit ] await.ready: %val = load i32, i32* %Result.i19 ``` Reviewers: majnemer Subscribers: llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D24418 llvm-svn: 282902
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/Transforms/Coroutines/coro-split-02.ll54
1 files changed, 54 insertions, 0 deletions
diff --git a/llvm/test/Transforms/Coroutines/coro-split-02.ll b/llvm/test/Transforms/Coroutines/coro-split-02.ll
new file mode 100644
index 00000000000..2326f77f198
--- /dev/null
+++ b/llvm/test/Transforms/Coroutines/coro-split-02.ll
@@ -0,0 +1,54 @@
+; Tests that coro-split can handle the case when a code after coro.suspend uses
+; a value produces between coro.save and coro.suspend (%Result.i19)
+; RUN: opt < %s -coro-split -S | FileCheck %s
+
+%"struct.std::coroutine_handle" = type { i8* }
+%"struct.std::coroutine_handle.0" = type { %"struct.std::coroutine_handle" }
+%"struct.lean_future<int>::Awaiter" = type { i32, %"struct.std::coroutine_handle.0" }
+
+declare i8* @malloc(i64)
+declare void @print(i32)
+
+define void @a() "coroutine.presplit"="1" {
+entry:
+ %ref.tmp7 = alloca %"struct.lean_future<int>::Awaiter", align 8
+ %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
+ %alloc = call i8* @malloc(i64 16) #3
+ %vFrame = call noalias nonnull i8* @llvm.coro.begin(token %id, i8* %alloc)
+
+ %save = call token @llvm.coro.save(i8* null)
+ %Result.i19 = getelementptr inbounds %"struct.lean_future<int>::Awaiter", %"struct.lean_future<int>::Awaiter"* %ref.tmp7, i64 0, i32 0
+ %suspend = call i8 @llvm.coro.suspend(token %save, i1 false)
+ switch i8 %suspend, label %exit [
+ i8 0, label %await.ready
+ i8 1, label %exit
+ ]
+await.ready:
+ %val = load i32, i32* %Result.i19
+ call void @print(i32 %val)
+ br label %exit
+exit:
+ call void @llvm.coro.end(i8* null, i1 false)
+ ret void
+}
+
+; CHECK-LABEL: @a.resume(
+; CHECK: getelementptr inbounds %a.Frame
+; CHECK-NEXT: getelementptr inbounds %"struct.lean_future<int>::Awaiter"
+; CHECK-NEXT: %val = load i32, i32* %Result
+; CHECK-NEXT: call void @print(i32 %val)
+; CHECK-NEXT: ret void
+
+declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*)
+declare i1 @llvm.coro.alloc(token) #3
+declare noalias nonnull i8* @"\01??2@YAPEAX_K@Z"(i64) local_unnamed_addr
+declare i64 @llvm.coro.size.i64() #5
+declare i8* @llvm.coro.begin(token, i8* writeonly) #3
+declare void @"\01?puts@@YAXZZ"(...)
+declare token @llvm.coro.save(i8*) #3
+declare i8* @llvm.coro.frame() #5
+declare i8 @llvm.coro.suspend(token, i1) #3
+declare void @"\01??3@YAXPEAX@Z"(i8*) local_unnamed_addr #10
+declare i8* @llvm.coro.free(token, i8* nocapture readonly) #2
+declare void @llvm.coro.end(i8*, i1) #3
+
OpenPOWER on IntegriCloud