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