xref: /llvm-project/clang/test/CodeGenCoroutines/coro-elide-thinlto.cpp (revision 533a22941e9acee1460fbd054fbfa57b82d660e5)
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