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