Skip to content

Commit 9d476e1

Browse files
authored
[clang][FatLTO] Avoid UnifiedLTO until it can support WPD/CFI (#79061)
Currently, the UnifiedLTO pipeline seems to have trouble with several LTO features, like SplitLTO units, which means we cannot use important optimizations like Whole Program Devirtualization or security hardening instrumentation like CFI. This patch reverts FatLTO to using distinct pipelines for Full LTO and ThinLTO. It still avoids module cloning, since that was error prone.
1 parent a829f10 commit 9d476e1

File tree

14 files changed

+92
-72
lines changed

14 files changed

+92
-72
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,8 +1001,9 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
10011001
}
10021002

10031003
if (CodeGenOpts.FatLTO) {
1004-
assert(CodeGenOpts.UnifiedLTO && "FatLTO requires UnifiedLTO");
1005-
MPM.addPass(PB.buildFatLTODefaultPipeline(Level));
1004+
MPM.addPass(PB.buildFatLTODefaultPipeline(
1005+
Level, PrepareForThinLTO,
1006+
PrepareForThinLTO || shouldEmitRegularLTOSummary()));
10061007
} else if (PrepareForThinLTO) {
10071008
MPM.addPass(PB.buildThinLTOPreLinkDefaultPipeline(Level));
10081009
} else if (PrepareForLTO) {
@@ -1073,8 +1074,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
10731074
if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
10741075
TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",
10751076
uint32_t(CodeGenOpts.EnableSplitLTOUnit));
1076-
// FatLTO always means UnifiedLTO
1077-
if (!TheModule->getModuleFlag("UnifiedLTO"))
1077+
if (CodeGenOpts.UnifiedLTO && !TheModule->getModuleFlag("UnifiedLTO"))
10781078
TheModule->addModuleFlag(llvm::Module::Error, "UnifiedLTO", uint32_t(1));
10791079
}
10801080

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4854,9 +4854,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
48544854
bool UnifiedLTO = false;
48554855
if (IsUsingLTO) {
48564856
UnifiedLTO = Args.hasFlag(options::OPT_funified_lto,
4857-
options::OPT_fno_unified_lto, Triple.isPS()) ||
4858-
Args.hasFlag(options::OPT_ffat_lto_objects,
4859-
options::OPT_fno_fat_lto_objects, false);
4857+
options::OPT_fno_unified_lto, Triple.isPS());
48604858
if (UnifiedLTO)
48614859
CmdArgs.push_back("-funified-lto");
48624860
}

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,20 +1861,6 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
18611861
if (Args.hasArg(OPT_funified_lto))
18621862
Opts.PrepareForThinLTO = true;
18631863
}
1864-
if (Arg *A = Args.getLastArg(options::OPT_ffat_lto_objects,
1865-
options::OPT_fno_fat_lto_objects)) {
1866-
if (A->getOption().matches(options::OPT_ffat_lto_objects)) {
1867-
if (Arg *Uni = Args.getLastArg(options::OPT_funified_lto,
1868-
options::OPT_fno_unified_lto)) {
1869-
if (Uni->getOption().matches(options::OPT_fno_unified_lto))
1870-
Diags.Report(diag::err_drv_incompatible_options)
1871-
<< A->getAsString(Args) << "-fno-unified-lto";
1872-
} else
1873-
Diags.Report(diag::err_drv_argument_only_allowed_with)
1874-
<< A->getAsString(Args) << "-funified-lto";
1875-
}
1876-
}
1877-
18781864
if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
18791865
if (IK.getLanguage() != Language::LLVM_IR)
18801866
Diags.Report(diag::err_drv_argument_only_allowed_with)

clang/test/CodeGen/fat-lto-objects.c

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,37 @@
11
// REQUIRES: x86-registered-target
22

3-
// RUN: not %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -ffat-lto-objects -fsplit-lto-unit -emit-llvm < %s 2>&1 | FileCheck %s --check-prefixes=NO-UNIFIED
3+
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -ffat-lto-objects -fsplit-lto-unit -emit-llvm < %s | FileCheck %s --check-prefixes=FULL,SPLIT
4+
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -ffat-lto-objects -emit-llvm < %s | FileCheck %s --check-prefixes=FULL,SPLIT
45

5-
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -funified-lto -ffat-lto-objects -fsplit-lto-unit -emit-llvm < %s | FileCheck %s --check-prefixes=FULL,SPLIT,UNIFIED
6-
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -funified-lto -ffat-lto-objects -emit-llvm < %s | FileCheck %s --check-prefixes=FULL,NOSPLIT,UNIFIED
6+
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -fsplit-lto-unit -ffat-lto-objects -emit-llvm < %s | FileCheck %s --check-prefixes=THIN,SPLIT
7+
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -ffat-lto-objects -emit-llvm < %s | FileCheck %s --check-prefixes=THIN,NOSPLIT
78

8-
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -funified-lto -fsplit-lto-unit -ffat-lto-objects -emit-llvm < %s | FileCheck %s --check-prefixes=THIN,SPLIT,UNIFIED
9-
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -funified-lto -ffat-lto-objects -emit-llvm < %s | FileCheck %s --check-prefixes=THIN,NOSPLIT,UNIFIED
10-
11-
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -funified-lto -ffat-lto-objects -fsplit-lto-unit -emit-obj < %s -o %t.full.split.o
9+
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -ffat-lto-objects -fsplit-lto-unit -emit-obj < %s -o %t.full.split.o
1210
// RUN: llvm-readelf -S %t.full.split.o | FileCheck %s --check-prefixes=ELF
1311
// RUN: llvm-objcopy --dump-section=.llvm.lto=%t.full.split.bc %t.full.split.o
14-
// RUN: llvm-dis %t.full.split.bc -o - | FileCheck %s --check-prefixes=THIN,SPLIT,UNIFIED
12+
// RUN: llvm-dis %t.full.split.bc -o - | FileCheck %s --check-prefixes=FULL,SPLIT,NOUNIFIED
1513

16-
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -funified-lto -ffat-lto-objects -emit-obj < %s -o %t.full.nosplit.o
14+
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -ffat-lto-objects -emit-obj < %s -o %t.full.nosplit.o
1715
// RUN: llvm-readelf -S %t.full.nosplit.o | FileCheck %s --check-prefixes=ELF
1816
// RUN: llvm-objcopy --dump-section=.llvm.lto=%t.full.nosplit.bc %t.full.nosplit.o
19-
// RUN: llvm-dis %t.full.nosplit.bc -o - | FileCheck %s --check-prefixes=THIN,NOSPLIT,UNIFIED
17+
// RUN: llvm-dis %t.full.nosplit.bc -o - | FileCheck %s --check-prefixes=FULL,NOSPLIT,NOUNIFIED
2018

21-
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -funified-lto -fsplit-lto-unit -ffat-lto-objects -emit-obj < %s -o %t.thin.split.o
19+
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -fsplit-lto-unit -ffat-lto-objects -emit-obj < %s -o %t.thin.split.o
2220
// RUN: llvm-readelf -S %t.thin.split.o | FileCheck %s --check-prefixes=ELF
2321
// RUN: llvm-objcopy --dump-section=.llvm.lto=%t.thin.split.bc %t.thin.split.o
24-
// RUN: llvm-dis %t.thin.split.bc -o - | FileCheck %s --check-prefixes=THIN,SPLIT,UNIFIED
22+
// RUN: llvm-dis %t.thin.split.bc -o - | FileCheck %s --check-prefixes=THIN,SPLIT,NOUNIFIED
2523

26-
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -funified-lto -ffat-lto-objects -emit-obj < %s -o %t.thin.nosplit.o
24+
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -ffat-lto-objects -emit-obj < %s -o %t.thin.nosplit.o
2725
// RUN: llvm-readelf -S %t.thin.nosplit.o | FileCheck %s --check-prefixes=ELF
2826
// RUN: llvm-objcopy --dump-section=.llvm.lto=%t.thin.nosplit.bc %t.thin.nosplit.o
29-
// RUN: llvm-dis %t.thin.nosplit.bc -o - | FileCheck %s --check-prefixes=THIN,NOSPLIT,UNIFIED
27+
// RUN: llvm-dis %t.thin.nosplit.bc -o - | FileCheck %s --check-prefixes=THIN,NOSPLIT,NOUNIFIED
28+
29+
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -funified-lto -ffat-lto-objects -emit-obj < %s -o %t.unified.o
30+
// RUN: llvm-readelf -S %t.unified.o | FileCheck %s --check-prefixes=ELF
31+
// RUN: llvm-objcopy --dump-section=.llvm.lto=%t.unified.bc %t.unified.o
32+
// RUN: llvm-dis %t.unified.bc -o - | FileCheck %s --check-prefixes=THIN,NOSPLIT,UNIFIED
3033

31-
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -funified-lto -ffat-lto-objects -fsplit-lto-unit -S < %s -o - \
34+
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -ffat-lto-objects -fsplit-lto-unit -S < %s -o - \
3235
// RUN: | FileCheck %s --check-prefixes=ASM
3336

3437
/// Be sure we enable split LTO units correctly under -ffat-lto-objects.
@@ -38,9 +41,8 @@
3841
// FULL-NOT: ![[#]] = !{i32 1, !"ThinLTO", i32 0}
3942
// THIN-NOT: ![[#]] = !{i32 1, !"ThinLTO", i32 0}
4043

41-
/// FatLTO always uses UnifiedLTO. It's an error if they aren't set together
42-
// UNIFIED: ![[#]] = !{i32 1, !"UnifiedLTO", i32 1}
43-
// NO-UNIFIED: error: invalid argument '-ffat-lto-objects' only allowed with '-funified-lto'
44+
// UNIFIED: ![[#]] = !{i32 1, !"UnifiedLTO", i32 1}
45+
// NOUNIFIED-NOT: ![[#]] = !{i32 1, !"UnifiedLTO", i32 1}
4446

4547
// ELF: .llvm.lto
4648

clang/test/Driver/fat-lto-objects.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// RUN: %clang --target=x86_64-unknown-linux-gnu -flto -ffat-lto-objects -### %s -c 2>&1 | FileCheck %s -check-prefix=CHECK-CC
22
// CHECK-CC: -cc1
3-
// CHECK-CC-SAME: -funified-lto
43
// CHECK-CC-SAME: -emit-obj
54
// CHECK-CC-SAME: -ffat-lto-objects
65

@@ -15,21 +14,18 @@
1514
/// When fat LTO is enabled with -S, we expect asm output and -ffat-lto-objects to be passed to cc1.
1615
// RUN: %clang --target=x86_64-unknown-linux-gnu -flto -ffat-lto-objects -### %s -S 2>&1 | FileCheck %s -check-prefix=CHECK-CC-S-LTO
1716
// CHECK-CC-S-LTO: -cc1
18-
// CHECK-CC-S-LTO-SAME: -funified-lto
1917
// CHECK-CC-S-NOT: -emit-llvm
2018
// CHECK-CC-S-LTO-SAME: -ffat-lto-objects
2119

2220
/// When fat LTO is enabled with -S and -emit-llvm, we expect IR output and -ffat-lto-objects to be passed to cc1.
2321
// RUN: %clang --target=x86_64-unknown-linux-gnu -flto -ffat-lto-objects -### %s -S -emit-llvm 2>&1 | FileCheck %s -check-prefix=CHECK-CC-S-EL-LTO
2422
// CHECK-CC-S-EL-LTO: -cc1
25-
// CHECK-CC-S-EL-LTO-SAME: -funified-lto
2623
// CHECK-CC-S-EL-LTO-SAME: -emit-llvm
2724
// CHECK-CC-S-EL-LTO-SAME: -ffat-lto-objects
2825

2926
/// When fat LTO is enabled wihtout -S we expect native object output and -ffat-lto-object to be passed to cc1.
3027
// RUN: %clang --target=x86_64-unknown-linux-gnu -flto -ffat-lto-objects -### %s -c 2>&1 | FileCheck %s -check-prefix=CHECK-CC-C-LTO
3128
// CHECK-CC-C-LTO: -cc1
32-
// CHECK-CC-C-LTO: -funified-lto
3329
// CHECK-CC-C-LTO: -emit-obj
3430
// CHECK-CC-C-LTO: -ffat-lto-objects
3531

@@ -47,13 +43,3 @@
4743
// RUN: -fuse-ld=lld -fno-lto -ffat-lto-objects -### 2>&1 | FileCheck --check-prefix=NOLTO %s
4844
// LTO: "--fat-lto-objects"
4945
// NOLTO-NOT: "--fat-lto-objects"
50-
51-
/// Make sure that incompatible options emit the correct diagnostics, since -ffat-lto-objects requires -funified-lto
52-
// RUN: %clang -cc1 -triple=x86_64-unknown-linux-gnu -flto -ffat-lto-objects -funified-lto -emit-llvm-only %s 2>&1 | FileCheck %s -check-prefix=UNIFIED --allow-empty
53-
// UNIFIED-NOT: error:
54-
55-
// RUN: not %clang -cc1 -triple=x86_64-unknown-linux-gnu -flto -ffat-lto-objects -emit-llvm-only %s 2>&1 | FileCheck %s -check-prefix=MISSING_UNIFIED
56-
// MISSING_UNIFIED: error: invalid argument '-ffat-lto-objects' only allowed with '-funified-lto'
57-
58-
// RUN: not %clang -cc1 -triple=x86_64-unknown-linux-gnu -flto -fno-unified-lto -ffat-lto-objects -emit-llvm-only %s 2>&1 | FileCheck %s -check-prefix=NO-UNIFIED
59-
// NO-UNIFIED: error: the combination of '-ffat-lto-objects' and '-fno-unified-lto' is incompatible

llvm/docs/FatLTO.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ Overview
2929
Within LLVM, FatLTO is supported by choosing the ``FatLTODefaultPipeline``.
3030
This pipeline will:
3131

32-
#) Run the pre-link UnifiedLTO pipeline on the current module.
32+
#) Run the pre-link (Thin)LTO pipeline on the current module.
3333
#) Embed the pre-link bitcode in a special ``.llvm.lto`` section.
34-
#) Finish optimizing the module using the post-link ThinLTO pipeline.
34+
#) Finish optimizing the module using the ModuleOptimization pipeline.
3535
#) Emit the object file, including the new ``.llvm.lto`` section.
3636

3737
.. NOTE

llvm/include/llvm/Passes/PassBuilder.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,9 @@ class PassBuilder {
250250
///
251251
/// This builds a pipeline that runs the LTO/ThinLTO pre-link pipeline, and
252252
/// emits a section containing the pre-link bitcode along side the object code
253-
/// generated by running the PerModuleDefaultPipeline, used when compiling
254-
/// without LTO. It clones the module and runs the LTO/non-LTO pipelines
255-
/// separately to avoid any inconsistencies with an ad-hoc pipeline that tries
256-
/// to approximate the PerModuleDefaultPipeline from the pre-link LTO
257-
/// pipelines.
258-
ModulePassManager buildFatLTODefaultPipeline(OptimizationLevel Level);
253+
/// generated in non-LTO compilation.
254+
ModulePassManager buildFatLTODefaultPipeline(OptimizationLevel Level,
255+
bool ThinLTO, bool EmitSummary);
259256

260257
/// Build a pre-link, ThinLTO-targeting default optimization pipeline to
261258
/// a pass manager.

llvm/include/llvm/Transforms/IPO/EmbedBitcodePass.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,25 @@ namespace llvm {
2424
class Module;
2525
class Pass;
2626

27+
struct EmbedBitcodeOptions {
28+
EmbedBitcodeOptions() : EmbedBitcodeOptions(false, false) {}
29+
EmbedBitcodeOptions(bool IsThinLTO, bool EmitLTOSummary)
30+
: IsThinLTO(IsThinLTO), EmitLTOSummary(EmitLTOSummary) {}
31+
bool IsThinLTO;
32+
bool EmitLTOSummary;
33+
};
34+
2735
/// Pass embeds a copy of the module optimized with the provided pass pipeline
2836
/// into a global variable.
2937
class EmbedBitcodePass : public PassInfoMixin<EmbedBitcodePass> {
30-
ModulePassManager MPM;
38+
bool IsThinLTO;
39+
bool EmitLTOSummary;
3140

3241
public:
33-
EmbedBitcodePass() {}
42+
EmbedBitcodePass(EmbedBitcodeOptions Opts)
43+
: EmbedBitcodePass(Opts.IsThinLTO, Opts.EmitLTOSummary) {}
44+
EmbedBitcodePass(bool IsThinLTO, bool EmitLTOSummary)
45+
: IsThinLTO(IsThinLTO), EmitLTOSummary(EmitLTOSummary) {}
3446

3547
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
3648

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,26 @@ Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
752752
return Result;
753753
}
754754

755+
Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
756+
EmbedBitcodeOptions Result;
757+
while (!Params.empty()) {
758+
StringRef ParamName;
759+
std::tie(ParamName, Params) = Params.split(';');
760+
761+
if (ParamName == "thinlto") {
762+
Result.IsThinLTO = true;
763+
} else if (ParamName == "emit-summary") {
764+
Result.EmitLTOSummary = true;
765+
} else {
766+
return make_error<StringError>(
767+
formatv("invalid EmbedBitcode pass parameter '{0}' ", ParamName)
768+
.str(),
769+
inconvertibleErrorCode());
770+
}
771+
}
772+
return Result;
773+
}
774+
755775
Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
756776
MemorySanitizerOptions Result;
757777
while (!Params.empty()) {

llvm/lib/Passes/PassBuilderPipelines.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,14 +1531,17 @@ PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level,
15311531
}
15321532

15331533
ModulePassManager
1534-
PassBuilder::buildFatLTODefaultPipeline(OptimizationLevel Level) {
1534+
PassBuilder::buildFatLTODefaultPipeline(OptimizationLevel Level, bool ThinLTO,
1535+
bool EmitSummary) {
15351536
ModulePassManager MPM;
1536-
// FatLTO always uses UnifiedLTO, so use the ThinLTOPreLink pipeline
1537-
MPM.addPass(buildThinLTOPreLinkDefaultPipeline(Level));
1538-
MPM.addPass(EmbedBitcodePass());
1537+
if (ThinLTO)
1538+
MPM.addPass(buildThinLTOPreLinkDefaultPipeline(Level));
1539+
else
1540+
MPM.addPass(buildLTOPreLinkDefaultPipeline(Level));
1541+
MPM.addPass(EmbedBitcodePass(ThinLTO, EmitSummary));
15391542

1540-
// Use the ThinLTO post-link pipeline with sample profiling, other
1541-
if (PGOOpt && PGOOpt->Action == PGOOptions::SampleUse)
1543+
// Use the ThinLTO post-link pipeline with sample profiling
1544+
if (ThinLTO && PGOOpt && PGOOpt->Action == PGOOptions::SampleUse)
15421545
MPM.addPass(buildThinLTODefaultPipeline(Level, /*ImportSummary=*/nullptr));
15431546
else {
15441547
// otherwise, just use module optimization

llvm/lib/Passes/PassRegistry.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ MODULE_PASS("dfsan", DataFlowSanitizerPass())
5858
MODULE_PASS("dot-callgraph", CallGraphDOTPrinterPass())
5959
MODULE_PASS("dxil-upgrade", DXILUpgradePass())
6060
MODULE_PASS("elim-avail-extern", EliminateAvailableExternallyPass())
61-
MODULE_PASS("embed-bitcode", EmbedBitcodePass())
6261
MODULE_PASS("extract-blocks", BlockExtractorPass({}, false))
6362
MODULE_PASS("forceattrs", ForceFunctionAttrsPass())
6463
MODULE_PASS("function-import", FunctionImportPass())
@@ -161,6 +160,10 @@ MODULE_PASS_WITH_PARAMS(
161160
"group-by-use;ignore-single-use;max-offset=N;merge-const;merge-external;"
162161
"no-group-by-use;no-ignore-single-use;no-merge-const;no-merge-external;"
163162
"size-only")
163+
MODULE_PASS_WITH_PARAMS(
164+
"embed-bitcode", "EmbedBitcodePass",
165+
[](EmbedBitcodeOptions Opts) { return EmbedBitcodePass(Opts); },
166+
parseEmbedBitcodePassOptions, "thinlto;emit-summary")
164167
MODULE_PASS_WITH_PARAMS(
165168
"globaldce", "GlobalDCEPass",
166169
[](bool InLTOPostLink) { return GlobalDCEPass(InLTOPostLink); },

llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/Transforms/IPO/EmbedBitcodePass.h"
10+
#include "llvm/Bitcode/BitcodeWriter.h"
11+
#include "llvm/Bitcode/BitcodeWriterPass.h"
1012
#include "llvm/IR/PassManager.h"
1113
#include "llvm/Pass.h"
1214
#include "llvm/Support/ErrorHandling.h"
@@ -16,6 +18,7 @@
1618
#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
1719
#include "llvm/Transforms/Utils/ModuleUtils.h"
1820

21+
#include <memory>
1922
#include <string>
2023

2124
using namespace llvm;
@@ -30,9 +33,16 @@ PreservedAnalyses EmbedBitcodePass::run(Module &M, ModuleAnalysisManager &AM) {
3033
report_fatal_error(
3134
"EmbedBitcode pass currently only supports ELF object format",
3235
/*gen_crash_diag=*/false);
36+
3337
std::string Data;
3438
raw_string_ostream OS(Data);
35-
ThinLTOBitcodeWriterPass(OS, /*ThinLinkOS=*/nullptr).run(M, AM);
39+
if (IsThinLTO)
40+
ThinLTOBitcodeWriterPass(OS, /*ThinLinkOS=*/nullptr).run(M, AM);
41+
else
42+
BitcodeWriterPass(OS, /*ShouldPreserveUseListOrder=*/false, EmitLTOSummary)
43+
.run(M, AM);
44+
3645
embedBufferInModule(M, MemoryBufferRef(Data, "ModuleData"), ".llvm.lto");
46+
3747
return PreservedAnalyses::all();
3848
}

llvm/test/CodeGen/X86/fat-lto-section.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
;; Ensure that the .llvm.lto section has SHT_EXCLUDE set.
2-
; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode" -S \
2+
; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode<thinlto;emit-summary>" -S \
33
; RUN: | llc --mtriple x86_64-unknown-linux-gnu -filetype=obj \
44
; RUN: | llvm-readelf - --sections \
55
; RUN: | FileCheck %s --check-prefix=EXCLUDE

llvm/test/Transforms/EmbedBitcode/embed.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode" -S | FileCheck %s
2+
; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode<thinlto>" -S | FileCheck %s
3+
; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode<emit-summary>" -S | FileCheck %s
4+
; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode<thinlto;emit-summary>" -S | FileCheck %s
25

36
@a = global i32 1
47

0 commit comments

Comments
 (0)