https://github.com/lenary updated https://github.com/llvm/llvm-project/pull/163692
>From 2b8462929be8e2542c995fbbc7a3d270372001f0 Mon Sep 17 00:00:00 2001 From: Sam Elliott <[email protected]> Date: Wed, 15 Oct 2025 20:54:03 -0700 Subject: [PATCH 1/2] [clang] Ensure -mno-outline adds attributes Before this change, `-mno-outline` and `-moutline` only controlled the pass pipelines for the invoked compiler/linker. The drawback of this implementation is that, when using LTO, only the flag provided to the linker invocation is honoured (and any files which individually use `-mno-outline` will have that flag ignored). This change serialises the `-mno-outline` flag into each function's IR/Bitcode, so that we can correctly disable outlining from functions in files which disabled outlining, without affecting outlining choices for functions from other files. This matches how other optimisation flags are handled so the IR/Bitcode can be correctly merged during LTO. --- clang/include/clang/Basic/CodeGenOptions.def | 3 +++ clang/include/clang/Options/Options.td | 17 +++++++---------- clang/lib/CodeGen/CodeGenModule.cpp | 4 +++- clang/lib/Driver/ToolChains/CommonArgs.cpp | 11 ++++++----- clang/test/CodeGen/attr-nooutline.c | 17 ++++++++++++++--- clang/test/Driver/aarch64-outliner.c | 2 +- clang/test/Driver/arm-machine-outliner.c | 2 +- clang/test/Driver/riscv-outliner.c | 2 +- clang/test/Driver/x86-outliner.c | 2 +- 9 files changed, 37 insertions(+), 23 deletions(-) diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 8c056bb690690..5e174b21be466 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -509,6 +509,9 @@ CODEGENOPT(AllResourcesBound, 1, 0, Benign) ENUM_CODEGENOPT(WinX64EHUnwindV2, WinX64EHUnwindV2Mode, 2, WinX64EHUnwindV2Mode::Disabled, Benign) +/// Adds attributes that prevent outlining (`-mno-outline`) +CODEGENOPT(DisableOutlining, 1, 0, Benign) + /// FIXME: Make DebugOptions its own top-level .def file. #include "DebugOptions.def" diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index ac973602b3517..0051ff7ffc75a 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -5297,16 +5297,13 @@ def mmacos_version_min_EQ : Joined<["-"], "mmacos-version-min=">, def : Joined<["-"], "mmacosx-version-min=">, Visibility<[ClangOption, CC1Option, FC1Option, FlangOption]>, Group<m_Group>, Alias<mmacos_version_min_EQ>; -def moutline - : Flag<["-"], "moutline">, - Group<f_clang_Group>, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable function outlining (AArch64,Arm,RISC-V,X86 only)">; -def mno_outline - : Flag<["-"], "mno-outline">, - Group<f_clang_Group>, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Disable function outlining (AArch64,Arm,RISC-V,X86 only)">; +defm outline + : BoolMOption< + "outline", CodeGenOpts<"DisableOutlining">, DefaultFalse, + NegFlag<SetTrue, [], [ClangOption, CC1Option], + "Disable function outlining (AArch64,Arm,RISC-V,X86 only)">, + PosFlag<SetFalse, [], [ClangOption], + "Enable function outlining (AArch64,Arm,RISC-V,X86 only)">>; def mms_bitfields : Flag<["-"], "mms-bitfields">, Group<m_Group>, HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard">; def mno_ms_bitfields : Flag<["-"], "mno-ms-bitfields">, Group<m_Group>, diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 6a087be3751f0..43b8af0b2156a 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2928,7 +2928,9 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, B.addAttribute(llvm::Attribute::MinSize); } - if (D->hasAttr<NoOutlineAttr>()) + // Add `nooutline` if Outlining is disabled with a command-line flag or a + // function attribute. + if (CodeGenOpts.DisableOutlining || D->hasAttr<NoOutlineAttr>()) B.addAttribute(llvm::Attribute::NoOutline); F->addFnAttrs(B); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 6857231b2aafe..f48e6c26c8995 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -2966,11 +2966,12 @@ void tools::addMachineOutlinerArgs(const Driver &D, D.Diag(diag::warn_drv_moutline_unsupported_opt) << Triple.getArchName(); } } else { - // Disable all outlining behaviour. - // - // FIXME: This should probably use the `nooutline` attribute rather than - // tweaking Pipeline Pass flags, so `-mno-outline` and `-moutline` objects - // can be combined correctly during LTO. + if (!IsLTO) + // Disable all outlining behaviour using `nooutline` attribute, in case + // Linker Invocation lacks `-mno-outline`. + CmdArgs.push_back("-mno-outline"); + + // Disable Pass in Pipeline addArg(Twine("-enable-machine-outliner=never")); } } diff --git a/clang/test/CodeGen/attr-nooutline.c b/clang/test/CodeGen/attr-nooutline.c index 8519414397a8b..6122b3247ba69 100644 --- a/clang/test/CodeGen/attr-nooutline.c +++ b/clang/test/CodeGen/attr-nooutline.c @@ -1,6 +1,17 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes --version 6 -// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s --check-prefix=C -// RUN: %clang_cc1 -emit-llvm -x c++ %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s --check-prefix=CXX +// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -DTEST_ATTR -o - | FileCheck %s --check-prefix=C +// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -mno-outline -o - | FileCheck %s --check-prefix=C +// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -mno-outline -DTEST_ATTR -o - | FileCheck %s --check-prefix=C + +// RUN: %clang_cc1 -emit-llvm -x c++ %s -triple x86_64-unknown-linux-gnu -DTEST_ATTR -o - | FileCheck %s --check-prefix=CXX +// RUN: %clang_cc1 -emit-llvm -x c++ %s -triple x86_64-unknown-linux-gnu -mno-outline -o - | FileCheck %s --check-prefix=CXX +// RUN: %clang_cc1 -emit-llvm -x c++ %s -triple x86_64-unknown-linux-gnu -mno-outline -DTEST_ATTR -o - | FileCheck %s --check-prefix=CXX + +#ifdef TEST_ATTR +#define NOOUTLINE [[clang::nooutline]] +#else +#define NOOUTLINE +#endif // C: Function Attrs: noinline nooutline nounwind optnone // C-LABEL: define dso_local i32 @t1( @@ -20,6 +31,6 @@ // CXX-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 // CXX-NEXT: ret i32 [[TMP0]] // -[[clang::nooutline]] int t1(int x) { +NOOUTLINE int t1(int x) { return x; } diff --git a/clang/test/Driver/aarch64-outliner.c b/clang/test/Driver/aarch64-outliner.c index 5ed822f122fc4..4d5b7321e330f 100644 --- a/clang/test/Driver/aarch64-outliner.c +++ b/clang/test/Driver/aarch64-outliner.c @@ -3,4 +3,4 @@ // ON: "-mllvm" "-enable-machine-outliner" // RUN: %clang --target=aarch64 -moutline -mno-outline -S %s -### 2>&1 | FileCheck %s -check-prefix=OFF // RUN: %clang --target=aarch64_be -moutline -mno-outline -S %s -### 2>&1 | FileCheck %s -check-prefix=OFF -// OFF: "-mllvm" "-enable-machine-outliner=never" +// OFF: "-mno-outline" "-mllvm" "-enable-machine-outliner=never" diff --git a/clang/test/Driver/arm-machine-outliner.c b/clang/test/Driver/arm-machine-outliner.c index a1e705cb60a1b..efa29d2ab8450 100644 --- a/clang/test/Driver/arm-machine-outliner.c +++ b/clang/test/Driver/arm-machine-outliner.c @@ -3,6 +3,6 @@ // RUN: %clang -target armv7-linux-gnueabihf -flto -moutline %s -### 2>&1 | FileCheck %s -check-prefix=ON-LTO // ON-LTO: "-plugin-opt=-enable-machine-outliner" // RUN: %clang -target armv7-linux-gnueabihf -moutline -mno-outline -c %s -### 2>&1 | FileCheck %s -check-prefix=OFF -// OFF: "-mllvm" "-enable-machine-outliner=never" +// OFF: "-mno-outline" "-mllvm" "-enable-machine-outliner=never" // RUN: %clang -target armv7-linux-gnueabihf -flto -moutline -mno-outline %s -### 2>&1 | FileCheck %s -check-prefix=OFF-LTO // OFF-LTO: "-plugin-opt=-enable-machine-outliner=never" diff --git a/clang/test/Driver/riscv-outliner.c b/clang/test/Driver/riscv-outliner.c index 9e9905ab4fd8a..fa69977331e13 100644 --- a/clang/test/Driver/riscv-outliner.c +++ b/clang/test/Driver/riscv-outliner.c @@ -4,4 +4,4 @@ // RUN: %clang --target=riscv32 -moutline -mno-outline -S %s -### 2>&1 | FileCheck %s -check-prefix=OFF // RUN: %clang --target=riscv64 -moutline -mno-outline -S %s -### 2>&1 | FileCheck %s -check-prefix=OFF -// OFF: "-mllvm" "-enable-machine-outliner=never" +// OFF: "-mno-outline" "-mllvm" "-enable-machine-outliner=never" diff --git a/clang/test/Driver/x86-outliner.c b/clang/test/Driver/x86-outliner.c index e2af85d3d16ab..7da56ac93fa5e 100644 --- a/clang/test/Driver/x86-outliner.c +++ b/clang/test/Driver/x86-outliner.c @@ -4,4 +4,4 @@ // RUN: %clang --target=i386 -moutline -mno-outline -S %s -### 2>&1 | FileCheck %s -check-prefix=OFF // RUN: %clang --target=x86_64 -moutline -mno-outline -S %s -### 2>&1 | FileCheck %s -check-prefix=OFF -// OFF: "-mllvm" "-enable-machine-outliner=never" +// OFF: "-mno-outline" "-mllvm" "-enable-machine-outliner=never" >From c61a512f30c0bd383a4df11e2d76846cb5994fae Mon Sep 17 00:00:00 2001 From: Sam Elliott <[email protected]> Date: Thu, 16 Oct 2025 13:51:23 -0700 Subject: [PATCH 2/2] Release Note --- clang/docs/ReleaseNotes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 3c40407faf9d1..56dedc49dd301 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -150,6 +150,8 @@ Deprecated Compiler Flags Modified Compiler Flags ----------------------- - The `-mno-outline` and `-moutline` compiler flags are now allowed on RISC-V and X86, which both support the machine outliner. +- The `-mno-outline` flag will now add the `nooutline` IR attribute, so that + `-mno-outline` and `-moutline` objects can be mixed correctly during LTO. Removed Compiler Flags ---------------------- _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
