aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authorPaul Kirth <paulkirth@google.com>2024-01-23 14:04:52 -0800
committerGitHub <noreply@github.com>2024-01-23 14:04:52 -0800
commit9d476e1e1a18af390e3455a6622ee67a69c64103 (patch)
treef4dfc7844153746db48b935dd4123f1d64cf7bd4 /clang
parenta829f109ffd518230df5191c64aa427603cf10d9 (diff)
downloadllvm-9d476e1e1a18af390e3455a6622ee67a69c64103.zip
llvm-9d476e1e1a18af390e3455a6622ee67a69c64103.tar.gz
llvm-9d476e1e1a18af390e3455a6622ee67a69c64103.tar.bz2
[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.
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp8
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp4
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp14
-rw-r--r--clang/test/CodeGen/fat-lto-objects.c38
-rw-r--r--clang/test/Driver/fat-lto-objects.c14
5 files changed, 25 insertions, 53 deletions
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index a6142d9..ec203f6 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -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) {
@@ -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));
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index bcba7cb..5dc614e 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -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");
}
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 7edea77..feb4de2 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -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)
diff --git a/clang/test/CodeGen/fat-lto-objects.c b/clang/test/CodeGen/fat-lto-objects.c
index 5c8ad1f..afce798 100644
--- a/clang/test/CodeGen/fat-lto-objects.c
+++ b/clang/test/CodeGen/fat-lto-objects.c
@@ -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.
@@ -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
diff --git a/clang/test/Driver/fat-lto-objects.c b/clang/test/Driver/fat-lto-objects.c
index 203175d6..97002db 100644
--- a/clang/test/Driver/fat-lto-objects.c
+++ b/clang/test/Driver/fat-lto-objects.c
@@ -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
@@ -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
@@ -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