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. 4 // 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 10 11 //--- coro-elide-task.h 12 #pragma once 13 #include "Inputs/coroutine.h" 14 15 struct 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 58 private: 59 std::coroutine_handle<promise_type> handle; 60 }; 61 62 //--- coro-elide-callee.cpp 63 #include "coro-elide-task.h" 64 Task task0() { 65 co_return 43; 66 } 67 68 //--- coro-elide-caller.cpp 69 #include "coro-elide-task.h" 70 71 Task task0(); 72 73 Task task1() { 74 co_return co_await task0(); 75 } 76 77 // CHECK-LABEL: define{{.*}} void @_Z5task1v.resume 78 // CHECK-NOT: {{.*}}_Znwm 79