1 // REQUIRES: x86_64-linux
2 // 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.
5 // RUN: split-file %s %t
6 // 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.bc
7 // 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.bc
8 // RUN: llvm-lto --thinlto %t/coro-elide-callee.bc %t/coro-elide-caller.bc -o %t/summary
9 // RUN: %clang_cc1 -O2 -x ir %t/coro-elide-caller.bc -fthinlto-index=%t/summary.thinlto.bc -emit-llvm -o - | FileCheck %s
11 //--- coro-elide-task.h
13 #include "Inputs/coroutine.h"
18 bool await_ready() const noexcept
{ return false; }
19 template <typename PromiseType
>
20 std::coroutine_handle
<> await_suspend(std::coroutine_handle
<PromiseType
> h
) noexcept
{
22 return std::noop_coroutine();
23 return h
.promise().continuation
;
25 void await_resume() noexcept
{}
27 Task
get_return_object() noexcept
{
28 return std::coroutine_handle
<promise_type
>::from_promise(*this);
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
{
36 std::coroutine_handle
<> continuation
;
40 Task(std::coroutine_handle
<promise_type
> handle
) : handle(handle
) {}
47 bool await_ready() const noexcept
{ return false; }
48 void await_suspend(std::coroutine_handle
<void> continuation
) noexcept
{}
49 int await_resume() noexcept
{
54 auto operator co_await() {
59 std::coroutine_handle
<promise_type
> handle
;
62 //--- coro-elide-callee.cpp
63 #include "coro-elide-task.h"
68 //--- coro-elide-caller.cpp
69 #include "coro-elide-task.h"
74 co_return co_await
task0();
77 // CHECK-LABEL: define{{.*}} void @_Z5task1v.resume
78 // CHECK-NOT: {{.*}}_Znwm