xref: /llvm-project/clang/test/CodeGenCoroutines/coro-elide.cpp (revision eaea793d5eb68d121dc773f6c31ebc2214bf1371)
1 // This tests that the coroutine elide optimization could happen succesfully.
2 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -O2 -emit-llvm %s -o - | FileCheck %s
3 
4 #include "Inputs/coroutine.h"
5 
6 struct Task {
7   struct promise_type {
8     struct FinalAwaiter {
await_readyTask::promise_type::FinalAwaiter9       bool await_ready() const noexcept { return false; }
10       template <typename PromiseType>
await_suspendTask::promise_type::FinalAwaiter11       std::coroutine_handle<> await_suspend(std::coroutine_handle<PromiseType> h) noexcept {
12         if (!h)
13           return std::noop_coroutine();
14         return h.promise().continuation;
15       }
await_resumeTask::promise_type::FinalAwaiter16       void await_resume() noexcept {}
17     };
get_return_objectTask::promise_type18     Task get_return_object() noexcept {
19       return std::coroutine_handle<promise_type>::from_promise(*this);
20     }
initial_suspendTask::promise_type21     std::suspend_always initial_suspend() noexcept { return {}; }
final_suspendTask::promise_type22     FinalAwaiter final_suspend() noexcept { return {}; }
unhandled_exceptionTask::promise_type23     void unhandled_exception() noexcept {}
return_valueTask::promise_type24     void return_value(int x) noexcept {
25       _value = x;
26     }
27     std::coroutine_handle<> continuation;
28     int _value;
29   };
30 
TaskTask31   Task(std::coroutine_handle<promise_type> handle) : handle(handle) {}
~TaskTask32   ~Task() {
33     if (handle)
34       handle.destroy();
35   }
36 
37   struct Awaiter {
await_readyTask::Awaiter38     bool await_ready() const noexcept { return false; }
await_suspendTask::Awaiter39     void await_suspend(std::coroutine_handle<void> continuation) noexcept {}
await_resumeTask::Awaiter40     int await_resume() noexcept {
41       return 43;
42     }
43   };
44 
operator co_awaitTask45   auto operator co_await() {
46     return Awaiter{};
47   }
48 
49 private:
50   std::coroutine_handle<promise_type> handle;
51 };
52 
task0()53 Task task0() {
54   co_return 43;
55 }
56 
task1()57 Task task1() {
58   co_return co_await task0();
59 }
60 
61 // CHECK-LABEL: define{{.*}} void @_Z5task1v.resume
62 // CHECK-NOT: call{{.*}}_Znwm
63