79 lines · cpp
1// REQUIRES: x86_64-linux2// This tests that the coroutine elide optimization could happen succesfully with ThinLTO.3// This test is adapted from coro-elide.cpp and splits functions into two files.4//5// RUN: split-file %s %t6// RUN: %clang --target=x86_64-linux -std=c++20 -O2 -flto=thin -I %S -c %t/coro-elide-callee.cpp -o %t/coro-elide-callee.bc7// RUN: %clang --target=x86_64-linux -std=c++20 -O2 -flto=thin -I %S -c %t/coro-elide-caller.cpp -o %t/coro-elide-caller.bc8// RUN: llvm-lto --thinlto %t/coro-elide-callee.bc %t/coro-elide-caller.bc -o %t/summary9// RUN: %clang_cc1 -O2 -x ir %t/coro-elide-caller.bc -fthinlto-index=%t/summary.thinlto.bc -emit-llvm -o - | FileCheck %s10 11//--- coro-elide-task.h12#pragma once13#include "Inputs/coroutine.h"14 15struct Task {16 struct promise_type {17 struct FinalAwaiter {18 bool await_ready() const noexcept { return false; }19 template <typename PromiseType>20 std::coroutine_handle<> await_suspend(std::coroutine_handle<PromiseType> h) noexcept {21 if (!h)22 return std::noop_coroutine();23 return h.promise().continuation;24 }25 void await_resume() noexcept {}26 };27 Task get_return_object() noexcept {28 return std::coroutine_handle<promise_type>::from_promise(*this);29 }30 std::suspend_always initial_suspend() noexcept { return {}; }31 FinalAwaiter final_suspend() noexcept { return {}; }32 void unhandled_exception() noexcept {}33 void return_value(int x) noexcept {34 _value = x;35 }36 std::coroutine_handle<> continuation;37 int _value;38 };39 40 Task(std::coroutine_handle<promise_type> handle) : handle(handle) {}41 ~Task() {42 if (handle)43 handle.destroy();44 }45 46 struct Awaiter {47 bool await_ready() const noexcept { return false; }48 void await_suspend(std::coroutine_handle<void> continuation) noexcept {}49 int await_resume() noexcept {50 return 43;51 }52 };53 54 auto operator co_await() {55 return Awaiter{};56 }57 58private:59 std::coroutine_handle<promise_type> handle;60};61 62//--- coro-elide-callee.cpp63#include "coro-elide-task.h"64Task task0() {65 co_return 43;66}67 68//--- coro-elide-caller.cpp69#include "coro-elide-task.h"70 71Task task0();72 73Task task1() {74 co_return co_await task0();75}76 77// CHECK-LABEL: define{{.*}} void @_Z5task1v.resume78// CHECK-NOT: {{.*}}_Znwm79