summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/Coroutines
diff options
context:
space:
mode:
authorGor Nishanov <GorNishanov@gmail.com>2017-01-25 02:25:54 +0000
committerGor Nishanov <GorNishanov@gmail.com>2017-01-25 02:25:54 +0000
commitdf3d71a7a9b4976c1aecf9eaf40c9ada55bf7879 (patch)
tree91dfccdf5cc7a0f8c96b26490f49ec131e9f6f32 /llvm/test/Transforms/Coroutines
parent99a1e0eba53d13fd0b3103068955db91d6265708 (diff)
downloadbcm5719-llvm-df3d71a7a9b4976c1aecf9eaf40c9ada55bf7879.tar.gz
bcm5719-llvm-df3d71a7a9b4976c1aecf9eaf40c9ada55bf7879.zip
[coroutines] Spill the result of the invoke instruction correctly
Summary: When we decide that the result of the invoke instruction need to be spilled, we need to insert the spill into a block that is on the normal edge coming out of the invoke instruction. (Prior to this change the code would insert the spill immediately after the invoke instruction, which breaks the IR, since invoke is a terminator instruction). In the following example, we will split the edge going into %cont and insert the spill there. ``` %r = invoke double @print(double 0.0) to label %cont unwind label %pad cont: %0 = call i8 @llvm.coro.suspend(token none, i1 false) switch i8 %0, label %suspend [i8 0, label %resume i8 1, label %cleanup] resume: call double @print(double %r) ``` Reviewers: majnemer Reviewed By: majnemer Subscribers: mehdi_amini, llvm-commits, EricWF Differential Revision: https://reviews.llvm.org/D29102 llvm-svn: 293006
Diffstat (limited to 'llvm/test/Transforms/Coroutines')
-rw-r--r--llvm/test/Transforms/Coroutines/coro-frame.ll61
1 files changed, 61 insertions, 0 deletions
diff --git a/llvm/test/Transforms/Coroutines/coro-frame.ll b/llvm/test/Transforms/Coroutines/coro-frame.ll
new file mode 100644
index 00000000000..a6b749e7a91
--- /dev/null
+++ b/llvm/test/Transforms/Coroutines/coro-frame.ll
@@ -0,0 +1,61 @@
+; Check that we can handle spills of the result of the invoke instruction
+; RUN: opt < %s -coro-split -S | FileCheck %s
+
+define i8* @f() "coroutine.presplit"="1" personality i32 0 {
+entry:
+ %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null)
+ %size = call i32 @llvm.coro.size.i32()
+ %alloc = call i8* @malloc(i32 %size)
+ %hdl = call i8* @llvm.coro.begin(token %id, i8* %alloc)
+ %r = invoke double @print(double 0.0) to label %cont unwind label %pad
+
+cont:
+ %0 = call i8 @llvm.coro.suspend(token none, i1 false)
+ switch i8 %0, label %suspend [i8 0, label %resume
+ i8 1, label %cleanup]
+resume:
+ call double @print(double %r)
+ br label %cleanup
+
+cleanup:
+ %mem = call i8* @llvm.coro.free(token %id, i8* %hdl)
+ call void @free(i8* %mem)
+ br label %suspend
+suspend:
+ call void @llvm.coro.end(i8* %hdl, i1 0)
+ ret i8* %hdl
+pad:
+ %tok = cleanuppad within none []
+ cleanupret from %tok unwind to caller
+}
+
+; See if the float was added to the frame
+; CHECK-LABEL: %f.Frame = type { void (%f.Frame*)*, void (%f.Frame*)*, i1, i1, double }
+
+; See if the float was spilled into the frame
+; CHECK-LABEL: @f(
+; CHECK: %r = call double @print(
+; CHECK: %r.spill.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i32 0, i32 4
+; CHECK: store double %r, double* %r.spill.addr
+; CHECK: ret i8* %hdl
+
+; See of the float was loaded from the frame
+; CHECK-LABEL: @f.resume(
+; CHECK: %r.reload = load double, double* %r.reload.addr
+; CHECK: call double @print(double %r.reload)
+; CHECK: ret void
+
+declare i8* @llvm.coro.free(token, i8*)
+declare i32 @llvm.coro.size.i32()
+declare i8 @llvm.coro.suspend(token, i1)
+declare void @llvm.coro.resume(i8*)
+declare void @llvm.coro.destroy(i8*)
+
+declare token @llvm.coro.id(i32, i8*, i8*, i8*)
+declare i1 @llvm.coro.alloc(token)
+declare i8* @llvm.coro.begin(token, i8*)
+declare void @llvm.coro.end(i8*, i1)
+
+declare noalias i8* @malloc(i32)
+declare double @print(double)
+declare void @free(i8*)
OpenPOWER on IntegriCloud