llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-coroutines Author: Paul Kirth (ilovepi) <details> <summary>Changes</summary> When coroutines are used w/ both -ffat-lto-objects and -flto=thin, the coroutine passes are not added to the optimization pipelines. Instead, just use the default ThinLTO pipeline to generate the ELF. Fixes #<!-- -->134409. --- Full diff: https://github.com/llvm/llvm-project/pull/134434.diff 2 Files Affected: - (added) clang/test/CodeGenCoroutines/pr134409.cpp (+42) - (modified) llvm/lib/Passes/PassBuilderPipelines.cpp (+8-3) ``````````diff diff --git a/clang/test/CodeGenCoroutines/pr134409.cpp b/clang/test/CodeGenCoroutines/pr134409.cpp new file mode 100644 index 0000000000000..3f3d95e191594 --- /dev/null +++ b/clang/test/CodeGenCoroutines/pr134409.cpp @@ -0,0 +1,42 @@ +// An end-to-end test to make sure coroutine passes are added for thinlto. + +// RUN: %clang_cc1 -std=c++23 -ffat-lto-objects -flto=thin -emit-llvm %s -O3 -o - \ +// RUN: | FileCheck %s + +#include "Inputs/coroutine.h" + +class BasicCoroutine { +public: + struct Promise { + BasicCoroutine get_return_object() { return BasicCoroutine {}; } + + void unhandled_exception() noexcept { } + + void return_void() noexcept { } + + std::suspend_never initial_suspend() noexcept { return {}; } + std::suspend_never final_suspend() noexcept { return {}; } + }; + using promise_type = Promise; +}; + +// COM: match the embedded module, so we don't match something in it by accident. +// CHECK: @llvm.embedded.object = {{.*}} +// CHECK: @llvm.compiler.used = {{.*}} + +BasicCoroutine coro() { +// CHECK: define {{.*}} void @_Z4corov() {{.*}} { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret void +// CHECK-NEXT: } + co_return; +} + +int main() { +// CHECK: define {{.*}} i32 @main() {{.*}} { +// CHECK-NEXT: entry: +// CHECK-NEXT: ret i32 0 +// CHECK-NEXT: } + coro(); +} + diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp index a18b36ba40754..4b15e0fb5c2a7 100644 --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -1688,10 +1688,15 @@ PassBuilder::buildFatLTODefaultPipeline(OptimizationLevel Level, bool ThinLTO, MPM.addPass( LowerTypeTestsPass(nullptr, nullptr, lowertypetests::DropTestKind::All)); - // Use the ThinLTO post-link pipeline with sample profiling - if (ThinLTO && PGOOpt && PGOOpt->Action == PGOOptions::SampleUse) + // ModuleSimplification does not run the coroutine passes for ThinLTOPreLink, + // so we need the coroutine passes to run for ThinLTO builds, otherwise they + // will miscompile. + if (ThinLTO) { + // TODO: determine how to only run the ThinLTODefaultPipeline when using + // sample profiling. Ideally, we'd be able to still use the module + // optimization pipeline, with additional cleanups for coroutines. MPM.addPass(buildThinLTODefaultPipeline(Level, /*ImportSummary=*/nullptr)); - else { + } else { // otherwise, just use module optimization MPM.addPass( buildModuleOptimizationPipeline(Level, ThinOrFullLTOPhase::None)); `````````` </details> https://github.com/llvm/llvm-project/pull/134434 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits