|
| 1 | +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 \ |
| 2 | +// RUN: -O0 -disable-llvm-passes -emit-llvm %s -o - \ |
| 3 | +// RUN: | FileCheck %s --check-prefix=FRONTEND |
| 4 | + |
| 5 | +// The output of O0 is highly redundant and hard to test. Also it is not good |
| 6 | +// limit the output of O0. So we test the optimized output from O0. The idea |
| 7 | +// is the optimizations shouldn't change the semantics of the program. |
| 8 | +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 \ |
| 9 | +// RUN: -O0 -emit-llvm %s -o - -disable-O0-optnone \ |
| 10 | +// RUN: | opt -passes='sroa,mem2reg,simplifycfg' -S | FileCheck %s --check-prefix=CHECK-O0 |
| 11 | + |
| 12 | +#include "Inputs/coroutine.h" |
| 13 | + |
| 14 | +// A simple awaiter type with an await_suspend method that can't be |
| 15 | +// inlined. |
| 16 | +struct Awaiter { |
| 17 | + const int& x; |
| 18 | + |
| 19 | + bool await_ready() { return false; } |
| 20 | + std::coroutine_handle<> await_suspend(const std::coroutine_handle<> h); |
| 21 | + void await_resume() {} |
| 22 | +}; |
| 23 | + |
| 24 | +struct MyTask { |
| 25 | + // A lazy promise with an await_transform method that supports awaiting |
| 26 | + // integer references using the Awaiter struct above. |
| 27 | + struct promise_type { |
| 28 | + MyTask get_return_object() { |
| 29 | + return MyTask{ |
| 30 | + std::coroutine_handle<promise_type>::from_promise(*this), |
| 31 | + }; |
| 32 | + } |
| 33 | + |
| 34 | + std::suspend_always initial_suspend() { return {}; } |
| 35 | + std::suspend_always final_suspend() noexcept { return {}; } |
| 36 | + void unhandled_exception(); |
| 37 | + |
| 38 | + auto await_transform(const int& x) { return Awaiter{x}; } |
| 39 | + }; |
| 40 | + |
| 41 | + std::coroutine_handle<> h; |
| 42 | +}; |
| 43 | + |
| 44 | +// A global array of integers. |
| 45 | +int g_array[32]; |
| 46 | + |
| 47 | +// A coroutine that awaits each integer in the global array. |
| 48 | +MyTask FooBar() { |
| 49 | + for (const int& x : g_array) { |
| 50 | + co_await x; |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | +// FRONTEND: define{{.*}}@_ZNKSt16coroutine_handleIvE7addressEv{{.*}}#[[address_attr:[0-9]+]] |
| 55 | +// FRONTEND: attributes #[[address_attr]] = {{.*}}alwaysinline |
| 56 | + |
| 57 | +// CHECK-O0: define{{.*}}@_Z6FooBarv.resume |
| 58 | +// CHECK-O0: call{{.*}}@_ZN7Awaiter13await_suspendESt16coroutine_handleIvE |
| 59 | +// CHECK-O0-NOT: store |
| 60 | +// CHECK-O0: ret void |
0 commit comments