summaryrefslogtreecommitdiff
path: root/test/CodeGenCoroutines
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCoroutines')
-rw-r--r--test/CodeGenCoroutines/coro-await.cpp18
-rw-r--r--test/CodeGenCoroutines/coro-dest-slot.cpp26
-rw-r--r--test/CodeGenCoroutines/coro-ret-void.cpp14
3 files changed, 58 insertions, 0 deletions
diff --git a/test/CodeGenCoroutines/coro-await.cpp b/test/CodeGenCoroutines/coro-await.cpp
index fc6559f1e0ad4..41881d7123379 100644
--- a/test/CodeGenCoroutines/coro-await.cpp
+++ b/test/CodeGenCoroutines/coro-await.cpp
@@ -12,6 +12,7 @@ template <>
struct coroutine_handle<void> {
void *ptr;
static coroutine_handle from_address(void *);
+ void *address();
};
template <typename Promise>
@@ -326,3 +327,20 @@ void AwaitReturnsLValue(double) {
// CHECK-NEXT: store %struct.RefTag* %[[RES3]], %struct.RefTag** %[[ZVAR]],
RefTag& z = co_yield 42;
}
+
+struct TailCallAwait {
+ bool await_ready();
+ std::experimental::coroutine_handle<> await_suspend(std::experimental::coroutine_handle<>);
+ void await_resume();
+};
+
+// CHECK-LABEL: @TestTailcall(
+extern "C" void TestTailcall() {
+ co_await TailCallAwait{};
+
+ // CHECK: %[[RESULT:.+]] = call i8* @_ZN13TailCallAwait13await_suspendENSt12experimental16coroutine_handleIvEE(%struct.TailCallAwait*
+ // CHECK: %[[COERCE:.+]] = getelementptr inbounds %"struct.std::experimental::coroutine_handle", %"struct.std::experimental::coroutine_handle"* %[[TMP:.+]], i32 0, i32 0
+ // CHECK: store i8* %[[RESULT]], i8** %[[COERCE]]
+ // CHECK: %[[ADDR:.+]] = call i8* @_ZNSt12experimental16coroutine_handleIvE7addressEv(%"struct.std::experimental::coroutine_handle"* %[[TMP]])
+ // CHECK: call void @llvm.coro.resume(i8* %[[ADDR]])
+}
diff --git a/test/CodeGenCoroutines/coro-dest-slot.cpp b/test/CodeGenCoroutines/coro-dest-slot.cpp
new file mode 100644
index 0000000000000..4c7395ba608c3
--- /dev/null
+++ b/test/CodeGenCoroutines/coro-dest-slot.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 -emit-llvm %s -o - -disable-llvm-passes | FileCheck %s
+
+#include "Inputs/coroutine.h"
+
+using namespace std::experimental;
+
+struct coro {
+ struct promise_type {
+ coro get_return_object();
+ suspend_always initial_suspend();
+ suspend_never final_suspend();
+ void return_void();
+ static void unhandled_exception();
+ };
+};
+
+extern "C" coro f(int) { co_return; }
+// Verify that cleanup.dest.slot is eliminated in a coroutine.
+// CHECK-LABEL: f(
+// CHECK: call void @_ZNSt12experimental13coroutines_v113suspend_never12await_resumeEv(
+// CHECK: %[[CLEANUP_DEST:.+]] = phi i32 [ 0, %{{.+}} ], [ 2, %{{.+}} ], [ 2, %{{.+}} ]
+// CHECK: call i8* @llvm.coro.free(
+// CHECK: switch i32 %cleanup.dest.slot.0, label %{{.+}} [
+// CHECK-NEXT: i32 0
+// CHECK-NEXT: i32 2
+// CHECK-NEXT: ]
diff --git a/test/CodeGenCoroutines/coro-ret-void.cpp b/test/CodeGenCoroutines/coro-ret-void.cpp
index 6b07f6ea1d642..6ebb44dfaefab 100644
--- a/test/CodeGenCoroutines/coro-ret-void.cpp
+++ b/test/CodeGenCoroutines/coro-ret-void.cpp
@@ -21,6 +21,20 @@ coro1 f() {
// CHECK: call void @_ZNSt12experimental13coroutines_v113suspend_never12await_resumeEv(%"struct.std::experimental::coroutines_v1::suspend_never"*
// CHECK: call void @_ZN5coro112promise_type11return_voidEv(%"struct.coro1::promise_type"* %__promise)
+struct A {
+ A();
+ ~A();
+};
+
+coro1 f2() {
+ co_return (void) A{};
+}
+
+// CHECK-LABEL: define void @_Z2f2v(
+// CHECK: call void @_ZN1AC1Ev(%struct.A* %[[AVar:.*]])
+// CHECK-NEXT: call void @_ZN1AD1Ev(%struct.A* %[[AVar]])
+// CHECK-NEXT: call void @_ZN5coro112promise_type11return_voidEv(%"struct.coro1::promise_type"*
+
struct coro2 {
struct promise_type {
coro2 get_return_object();