Skip to content

Commit 7bf068a

Browse files
committed
[fatlto] Use the ThinLTO default pipeline for FatLTO
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.
1 parent 5942f02 commit 7bf068a

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// An end-to-end test to make sure coroutine passes are added for thinlto.
2+
3+
// RUN: %clang_cc1 -std=c++23 -ffat-lto-objects -flto=thin -emit-llvm %s -O3 -o - \
4+
// RUN: | FileCheck %s
5+
6+
#include "Inputs/coroutine.h"
7+
8+
class BasicCoroutine {
9+
public:
10+
struct Promise {
11+
BasicCoroutine get_return_object() { return BasicCoroutine {}; }
12+
13+
void unhandled_exception() noexcept { }
14+
15+
void return_void() noexcept { }
16+
17+
std::suspend_never initial_suspend() noexcept { return {}; }
18+
std::suspend_never final_suspend() noexcept { return {}; }
19+
};
20+
using promise_type = Promise;
21+
};
22+
23+
// COM: match the embedded module, so we don't match something in it by accident.
24+
// CHECK: @llvm.embedded.object = {{.*}}
25+
// CHECK: @llvm.compiler.used = {{.*}}
26+
27+
BasicCoroutine coro() {
28+
// CHECK: define {{.*}} void @_Z4corov() {{.*}} {
29+
// CHECK-NEXT: entry:
30+
// CHECK-NEXT: ret void
31+
// CHECK-NEXT: }
32+
co_return;
33+
}
34+
35+
int main() {
36+
// CHECK: define {{.*}} i32 @main() {{.*}} {
37+
// CHECK-NEXT: entry:
38+
// CHECK-NEXT: ret i32 0
39+
// CHECK-NEXT: }
40+
coro();
41+
}
42+

llvm/lib/Passes/PassBuilderPipelines.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,10 +1688,15 @@ PassBuilder::buildFatLTODefaultPipeline(OptimizationLevel Level, bool ThinLTO,
16881688
MPM.addPass(
16891689
LowerTypeTestsPass(nullptr, nullptr, lowertypetests::DropTestKind::All));
16901690

1691-
// Use the ThinLTO post-link pipeline with sample profiling
1692-
if (ThinLTO && PGOOpt && PGOOpt->Action == PGOOptions::SampleUse)
1691+
// ModuleSimplification does not run the coroutine passes for ThinLTOPreLink,
1692+
// so we need the coroutine passes to run for ThinLTO builds, otherwise they
1693+
// will miscompile.
1694+
if (ThinLTO) {
1695+
// TODO: determine how to only run the ThinLTODefaultPipeline when using
1696+
// sample profiling. Ideally, we'd be able to still use the module
1697+
// optimization pipeline, with additional cleanups for coroutines.
16931698
MPM.addPass(buildThinLTODefaultPipeline(Level, /*ImportSummary=*/nullptr));
1694-
else {
1699+
} else {
16951700
// otherwise, just use module optimization
16961701
MPM.addPass(
16971702
buildModuleOptimizationPipeline(Level, ThinOrFullLTOPhase::None));

0 commit comments

Comments
 (0)