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 XuTask task0() { 54bf5f2354SChuanqi Xu co_return 43; 55bf5f2354SChuanqi Xu } 56bf5f2354SChuanqi Xu task1()57bf5f2354SChuanqi XuTask 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