Skip to content

[clang][FatLTO] Avoid UnifiedLTO until it can support WPD/CFI #79061

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1001,8 +1001,9 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
}

if (CodeGenOpts.FatLTO) {
assert(CodeGenOpts.UnifiedLTO && "FatLTO requires UnifiedLTO");
MPM.addPass(PB.buildFatLTODefaultPipeline(Level));
MPM.addPass(PB.buildFatLTODefaultPipeline(
Level, PrepareForThinLTO,
PrepareForThinLTO || shouldEmitRegularLTOSummary()));
} else if (PrepareForThinLTO) {
MPM.addPass(PB.buildThinLTOPreLinkDefaultPipeline(Level));
} else if (PrepareForLTO) {
Expand Down Expand Up @@ -1073,8 +1074,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",
uint32_t(CodeGenOpts.EnableSplitLTOUnit));
// FatLTO always means UnifiedLTO
if (!TheModule->getModuleFlag("UnifiedLTO"))
if (CodeGenOpts.UnifiedLTO && !TheModule->getModuleFlag("UnifiedLTO"))
TheModule->addModuleFlag(llvm::Module::Error, "UnifiedLTO", uint32_t(1));
}

Expand Down
4 changes: 1 addition & 3 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4854,9 +4854,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
bool UnifiedLTO = false;
if (IsUsingLTO) {
UnifiedLTO = Args.hasFlag(options::OPT_funified_lto,
options::OPT_fno_unified_lto, Triple.isPS()) ||
Args.hasFlag(options::OPT_ffat_lto_objects,
options::OPT_fno_fat_lto_objects, false);
options::OPT_fno_unified_lto, Triple.isPS());
if (UnifiedLTO)
CmdArgs.push_back("-funified-lto");
}
Expand Down
14 changes: 0 additions & 14 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1861,20 +1861,6 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
if (Args.hasArg(OPT_funified_lto))
Opts.PrepareForThinLTO = true;
}
if (Arg *A = Args.getLastArg(options::OPT_ffat_lto_objects,
options::OPT_fno_fat_lto_objects)) {
if (A->getOption().matches(options::OPT_ffat_lto_objects)) {
if (Arg *Uni = Args.getLastArg(options::OPT_funified_lto,
options::OPT_fno_unified_lto)) {
if (Uni->getOption().matches(options::OPT_fno_unified_lto))
Diags.Report(diag::err_drv_incompatible_options)
<< A->getAsString(Args) << "-fno-unified-lto";
} else
Diags.Report(diag::err_drv_argument_only_allowed_with)
<< A->getAsString(Args) << "-funified-lto";
}
}

if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
if (IK.getLanguage() != Language::LLVM_IR)
Diags.Report(diag::err_drv_argument_only_allowed_with)
Expand Down
38 changes: 20 additions & 18 deletions clang/test/CodeGen/fat-lto-objects.c
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
// REQUIRES: x86-registered-target

// 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
// 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
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=full -ffat-lto-objects -emit-llvm < %s | FileCheck %s --check-prefixes=FULL,SPLIT

// 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
// 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
// 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
// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -ffat-lto-objects -emit-llvm < %s | FileCheck %s --check-prefixes=THIN,NOSPLIT

// 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
// 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

// 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
// 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
// RUN: llvm-readelf -S %t.full.split.o | FileCheck %s --check-prefixes=ELF
// RUN: llvm-objcopy --dump-section=.llvm.lto=%t.full.split.bc %t.full.split.o
// RUN: llvm-dis %t.full.split.bc -o - | FileCheck %s --check-prefixes=THIN,SPLIT,UNIFIED
// RUN: llvm-dis %t.full.split.bc -o - | FileCheck %s --check-prefixes=FULL,SPLIT,NOUNIFIED

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

// 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
// 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
// RUN: llvm-readelf -S %t.thin.split.o | FileCheck %s --check-prefixes=ELF
// RUN: llvm-objcopy --dump-section=.llvm.lto=%t.thin.split.bc %t.thin.split.o
// RUN: llvm-dis %t.thin.split.bc -o - | FileCheck %s --check-prefixes=THIN,SPLIT,UNIFIED
// RUN: llvm-dis %t.thin.split.bc -o - | FileCheck %s --check-prefixes=THIN,SPLIT,NOUNIFIED

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

// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -flto=thin -funified-lto -ffat-lto-objects -emit-obj < %s -o %t.unified.o
// RUN: llvm-readelf -S %t.unified.o | FileCheck %s --check-prefixes=ELF
// RUN: llvm-objcopy --dump-section=.llvm.lto=%t.unified.bc %t.unified.o
// RUN: llvm-dis %t.unified.bc -o - | FileCheck %s --check-prefixes=THIN,NOSPLIT,UNIFIED

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

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

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

// ELF: .llvm.lto

Expand Down
14 changes: 0 additions & 14 deletions clang/test/Driver/fat-lto-objects.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// RUN: %clang --target=x86_64-unknown-linux-gnu -flto -ffat-lto-objects -### %s -c 2>&1 | FileCheck %s -check-prefix=CHECK-CC
// CHECK-CC: -cc1
// CHECK-CC-SAME: -funified-lto
// CHECK-CC-SAME: -emit-obj
// CHECK-CC-SAME: -ffat-lto-objects

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

/// When fat LTO is enabled with -S and -emit-llvm, we expect IR output and -ffat-lto-objects to be passed to cc1.
// 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
// CHECK-CC-S-EL-LTO: -cc1
// CHECK-CC-S-EL-LTO-SAME: -funified-lto
// CHECK-CC-S-EL-LTO-SAME: -emit-llvm
// CHECK-CC-S-EL-LTO-SAME: -ffat-lto-objects

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

Expand All @@ -47,13 +43,3 @@
// RUN: -fuse-ld=lld -fno-lto -ffat-lto-objects -### 2>&1 | FileCheck --check-prefix=NOLTO %s
// LTO: "--fat-lto-objects"
// NOLTO-NOT: "--fat-lto-objects"

/// Make sure that incompatible options emit the correct diagnostics, since -ffat-lto-objects requires -funified-lto
// 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
// UNIFIED-NOT: error:

// 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
// MISSING_UNIFIED: error: invalid argument '-ffat-lto-objects' only allowed with '-funified-lto'

// 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
// NO-UNIFIED: error: the combination of '-ffat-lto-objects' and '-fno-unified-lto' is incompatible
4 changes: 2 additions & 2 deletions llvm/docs/FatLTO.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ Overview
Within LLVM, FatLTO is supported by choosing the ``FatLTODefaultPipeline``.
This pipeline will:

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

.. NOTE
Expand Down
9 changes: 3 additions & 6 deletions llvm/include/llvm/Passes/PassBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,9 @@ class PassBuilder {
///
/// This builds a pipeline that runs the LTO/ThinLTO pre-link pipeline, and
/// emits a section containing the pre-link bitcode along side the object code
/// generated by running the PerModuleDefaultPipeline, used when compiling
/// without LTO. It clones the module and runs the LTO/non-LTO pipelines
/// separately to avoid any inconsistencies with an ad-hoc pipeline that tries
/// to approximate the PerModuleDefaultPipeline from the pre-link LTO
/// pipelines.
ModulePassManager buildFatLTODefaultPipeline(OptimizationLevel Level);
/// generated in non-LTO compilation.
ModulePassManager buildFatLTODefaultPipeline(OptimizationLevel Level,
bool ThinLTO, bool EmitSummary);

/// Build a pre-link, ThinLTO-targeting default optimization pipeline to
/// a pass manager.
Expand Down
16 changes: 14 additions & 2 deletions llvm/include/llvm/Transforms/IPO/EmbedBitcodePass.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,25 @@ namespace llvm {
class Module;
class Pass;

struct EmbedBitcodeOptions {
EmbedBitcodeOptions() : EmbedBitcodeOptions(false, false) {}
EmbedBitcodeOptions(bool IsThinLTO, bool EmitLTOSummary)
: IsThinLTO(IsThinLTO), EmitLTOSummary(EmitLTOSummary) {}
bool IsThinLTO;
bool EmitLTOSummary;
};

/// Pass embeds a copy of the module optimized with the provided pass pipeline
/// into a global variable.
class EmbedBitcodePass : public PassInfoMixin<EmbedBitcodePass> {
ModulePassManager MPM;
bool IsThinLTO;
bool EmitLTOSummary;

public:
EmbedBitcodePass() {}
EmbedBitcodePass(EmbedBitcodeOptions Opts)
: EmbedBitcodePass(Opts.IsThinLTO, Opts.EmitLTOSummary) {}
EmbedBitcodePass(bool IsThinLTO, bool EmitLTOSummary)
: IsThinLTO(IsThinLTO), EmitLTOSummary(EmitLTOSummary) {}

PreservedAnalyses run(Module &M, ModuleAnalysisManager &);

Expand Down
20 changes: 20 additions & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,26 @@ Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
return Result;
}

Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
EmbedBitcodeOptions Result;
while (!Params.empty()) {
StringRef ParamName;
std::tie(ParamName, Params) = Params.split(';');

if (ParamName == "thinlto") {
Result.IsThinLTO = true;
} else if (ParamName == "emit-summary") {
Result.EmitLTOSummary = true;
} else {
return make_error<StringError>(
formatv("invalid EmbedBitcode pass parameter '{0}' ", ParamName)
.str(),
inconvertibleErrorCode());
}
}
return Result;
}

Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
MemorySanitizerOptions Result;
while (!Params.empty()) {
Expand Down
15 changes: 9 additions & 6 deletions llvm/lib/Passes/PassBuilderPipelines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1531,14 +1531,17 @@ PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level,
}

ModulePassManager
PassBuilder::buildFatLTODefaultPipeline(OptimizationLevel Level) {
PassBuilder::buildFatLTODefaultPipeline(OptimizationLevel Level, bool ThinLTO,
bool EmitSummary) {
ModulePassManager MPM;
// FatLTO always uses UnifiedLTO, so use the ThinLTOPreLink pipeline
MPM.addPass(buildThinLTOPreLinkDefaultPipeline(Level));
MPM.addPass(EmbedBitcodePass());
if (ThinLTO)
MPM.addPass(buildThinLTOPreLinkDefaultPipeline(Level));
else
MPM.addPass(buildLTOPreLinkDefaultPipeline(Level));
MPM.addPass(EmbedBitcodePass(ThinLTO, EmitSummary));

// Use the ThinLTO post-link pipeline with sample profiling, other
if (PGOOpt && PGOOpt->Action == PGOOptions::SampleUse)
// Use the ThinLTO post-link pipeline with sample profiling
if (ThinLTO && PGOOpt && PGOOpt->Action == PGOOptions::SampleUse)
MPM.addPass(buildThinLTODefaultPipeline(Level, /*ImportSummary=*/nullptr));
else {
// otherwise, just use module optimization
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/Passes/PassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ MODULE_PASS("dfsan", DataFlowSanitizerPass())
MODULE_PASS("dot-callgraph", CallGraphDOTPrinterPass())
MODULE_PASS("dxil-upgrade", DXILUpgradePass())
MODULE_PASS("elim-avail-extern", EliminateAvailableExternallyPass())
MODULE_PASS("embed-bitcode", EmbedBitcodePass())
MODULE_PASS("extract-blocks", BlockExtractorPass({}, false))
MODULE_PASS("forceattrs", ForceFunctionAttrsPass())
MODULE_PASS("function-import", FunctionImportPass())
Expand Down Expand Up @@ -161,6 +160,10 @@ MODULE_PASS_WITH_PARAMS(
"group-by-use;ignore-single-use;max-offset=N;merge-const;merge-external;"
"no-group-by-use;no-ignore-single-use;no-merge-const;no-merge-external;"
"size-only")
MODULE_PASS_WITH_PARAMS(
"embed-bitcode", "EmbedBitcodePass",
[](EmbedBitcodeOptions Opts) { return EmbedBitcodePass(Opts); },
parseEmbedBitcodePassOptions, "thinlto;emit-summary")
MODULE_PASS_WITH_PARAMS(
"globaldce", "GlobalDCEPass",
[](bool InLTOPostLink) { return GlobalDCEPass(InLTOPostLink); },
Expand Down
12 changes: 11 additions & 1 deletion llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO/EmbedBitcodePass.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Support/ErrorHandling.h"
Expand All @@ -16,6 +18,7 @@
#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"

#include <memory>
#include <string>

using namespace llvm;
Expand All @@ -30,9 +33,16 @@ PreservedAnalyses EmbedBitcodePass::run(Module &M, ModuleAnalysisManager &AM) {
report_fatal_error(
"EmbedBitcode pass currently only supports ELF object format",
/*gen_crash_diag=*/false);

std::string Data;
raw_string_ostream OS(Data);
ThinLTOBitcodeWriterPass(OS, /*ThinLinkOS=*/nullptr).run(M, AM);
if (IsThinLTO)
ThinLTOBitcodeWriterPass(OS, /*ThinLinkOS=*/nullptr).run(M, AM);
else
BitcodeWriterPass(OS, /*ShouldPreserveUseListOrder=*/false, EmitLTOSummary)
.run(M, AM);

embedBufferInModule(M, MemoryBufferRef(Data, "ModuleData"), ".llvm.lto");

return PreservedAnalyses::all();
}
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/fat-lto-section.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
;; Ensure that the .llvm.lto section has SHT_EXCLUDE set.
; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode" -S \
; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode<thinlto;emit-summary>" -S \
; RUN: | llc --mtriple x86_64-unknown-linux-gnu -filetype=obj \
; RUN: | llvm-readelf - --sections \
; RUN: | FileCheck %s --check-prefix=EXCLUDE
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/Transforms/EmbedBitcode/embed.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode" -S | FileCheck %s
; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode<thinlto>" -S | FileCheck %s
; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode<emit-summary>" -S | FileCheck %s
; RUN: opt --mtriple x86_64-unknown-linux-gnu < %s -passes="embed-bitcode<thinlto;emit-summary>" -S | FileCheck %s

@a = global i32 1

Expand Down