diff options
Diffstat (limited to 'test/CodeGenCoroutines')
-rw-r--r-- | test/CodeGenCoroutines/coro-await.cpp | 18 | ||||
-rw-r--r-- | test/CodeGenCoroutines/coro-dest-slot.cpp | 26 | ||||
-rw-r--r-- | test/CodeGenCoroutines/coro-ret-void.cpp | 14 |
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(); |