llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-driver Author: Peter Collingbourne (pcc) <details> <summary>Changes</summary> This option may be used to specify a function's preferred alignment. The -falign-functions option and the aligned attribute now control both the minimum alignment and the preferred alignment for consistency with gcc. In contrast to the previous approach implemented in #<!-- -->149444 the preferred alignment is retained for member functions. Part of this RFC: https://discourse.llvm.org/t/rfc-enhancing-function-alignment-attributes/88019 --- Full diff: https://github.com/llvm/llvm-project/pull/155528.diff 7 Files Affected: - (modified) clang/include/clang/Basic/LangOptions.def (+1) - (modified) clang/include/clang/Driver/Options.td (+5) - (modified) clang/lib/CodeGen/CodeGenModule.cpp (+13-7) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+13) - (added) clang/test/CodeGen/prefalign.c (+4) - (modified) clang/test/CodeGenCXX/member-alignment.cpp (+3-3) - (added) clang/test/Driver/prefalign.c (+5) ``````````diff diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index f094ba112988f..19bdc43abaac0 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -418,6 +418,7 @@ ENUM_LANGOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest, NotCompatible, "with") VALUE_LANGOPT(FunctionAlignment, 5, 0, Compatible, "Default alignment for functions") +VALUE_LANGOPT(PreferredFunctionAlignment, 5, 0, Compatible, "Preferred alignment for functions") VALUE_LANGOPT(LoopAlignment, 32, 0, Compatible, "Default alignment for loops") LANGOPT(FixedPoint, 1, 0, NotCompatible, "fixed point types") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 82e8212bee12d..2dfc0872bac1f 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1550,6 +1550,8 @@ defm access_control : BoolFOption<"access-control", PosFlag<SetTrue>>; def falign_functions : Flag<["-"], "falign-functions">, Group<f_Group>; def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<f_Group>; +def fpreferred_function_alignment_EQ : + Joined<["-"], "fpreferred-function-alignment=">, Group<f_Group>; def falign_loops_EQ : Joined<["-"], "falign-loops=">, Group<f_Group>, Visibility<[ClangOption, CC1Option]>, MetaVarName<"<N>">, HelpText<"N must be a power of two. Align loops to the boundary">, @@ -8446,6 +8448,9 @@ def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signa def function_alignment : Separate<["-"], "function-alignment">, HelpText<"default alignment for functions">, MarshallingInfoInt<LangOpts<"FunctionAlignment">>; +def preferred_function_alignment : Separate<["-"], "preferred-function-alignment">, + HelpText<"preferred alignment for functions">, + MarshallingInfoInt<LangOpts<"PreferredFunctionAlignment">>; def fhalf_no_semantic_interposition : Flag<["-"], "fhalf-no-semantic-interposition">, HelpText<"Like -fno-semantic-interposition but don't use local aliases">, MarshallingInfoFlag<LangOpts<"HalfNoSemanticInterposition">>; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 7064421fe0613..e7d94ed878e10 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2794,13 +2794,19 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, F->addFnAttrs(B); - unsigned alignment = D->getMaxAlignment() / Context.getCharWidth(); - if (alignment) - F->setAlignment(llvm::Align(alignment)); - - if (!D->hasAttr<AlignedAttr>()) - if (LangOpts.FunctionAlignment) - F->setAlignment(llvm::Align(1ull << LangOpts.FunctionAlignment)); + llvm::MaybeAlign ExplicitAlignment; + if (unsigned alignment = D->getMaxAlignment() / Context.getCharWidth()) + ExplicitAlignment = llvm::Align(alignment); + else if (LangOpts.FunctionAlignment) + ExplicitAlignment = llvm::Align(1ull << LangOpts.FunctionAlignment); + + if (ExplicitAlignment) { + F->setAlignment(ExplicitAlignment); + F->setPreferredAlignment(ExplicitAlignment); + } else if (LangOpts.PreferredFunctionAlignment) { + F->setPreferredAlignment( + llvm::Align(1ull << LangOpts.PreferredFunctionAlignment)); + } // Some C++ ABIs require 2-byte alignment for member functions, in order to // reserve a bit for differentiating between virtual and non-virtual member diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 1b44090534e82..c2ab8d9318a33 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -46,6 +46,7 @@ #include "llvm/Support/Compression.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/YAMLParser.h" @@ -5503,6 +5504,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(std::to_string(FunctionAlignment))); } + if (const Arg *A = Args.getLastArg(options::OPT_fpreferred_function_alignment_EQ)) { + unsigned Value = 0; + if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 65536 || + !llvm::isPowerOf2_32(Value)) + TC.getDriver().Diag(diag::err_drv_invalid_int_value) + << A->getAsString(Args) << A->getValue(); + + CmdArgs.push_back("-preferred-function-alignment"); + CmdArgs.push_back(Args.MakeArgString( + std::to_string(llvm::Log2_32_Ceil(std::min(Value, 65536u))))); + } + // We support -falign-loops=N where N is a power of 2. GCC supports more // forms. if (const Arg *A = Args.getLastArg(options::OPT_falign_loops_EQ)) { diff --git a/clang/test/CodeGen/prefalign.c b/clang/test/CodeGen/prefalign.c new file mode 100644 index 0000000000000..2370585a8e457 --- /dev/null +++ b/clang/test/CodeGen/prefalign.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-linux -preferred-function-alignment 4 %s -o - | FileCheck %s + +// CHECK: define {{.*}} void @f() {{.*}} prefalign 16 +void f() {} diff --git a/clang/test/CodeGenCXX/member-alignment.cpp b/clang/test/CodeGenCXX/member-alignment.cpp index d5c9a5a02b160..37ee733e18ff5 100644 --- a/clang/test/CodeGenCXX/member-alignment.cpp +++ b/clang/test/CodeGenCXX/member-alignment.cpp @@ -31,9 +31,9 @@ class t { [[gnu::aligned(16)]] void t::baz(void) { -// CHECK-NOEXTRAALIGN: @_ZN1t3bazEv({{.*}}) #0 align 16 { -// CHECK-EXTRAALIGN: @_ZN1t3bazEv({{.*}}) #0 align 16 { -// CHECK-MSVC: @"?baz@t@@QEAAXXZ"({{.*}}) #0 align 16 { +// CHECK-NOEXTRAALIGN: @_ZN1t3bazEv({{.*}}) #0 align 16 prefalign 16 { +// CHECK-EXTRAALIGN: @_ZN1t3bazEv({{.*}}) #0 align 16 prefalign 16 { +// CHECK-MSVC: @"?baz@t@@QEAAXXZ"({{.*}}) #0 align 16 prefalign 16 { } void diff --git a/clang/test/Driver/prefalign.c b/clang/test/Driver/prefalign.c new file mode 100644 index 0000000000000..de52f2dcf28bc --- /dev/null +++ b/clang/test/Driver/prefalign.c @@ -0,0 +1,5 @@ +// RUN: %clang -### -fpreferred-function-alignment=16 %s 2>&1 | FileCheck %s -check-prefix CHECK-16 +// RUN: not %clang -### -fpreferred-function-alignment=3 %s 2>&1 | FileCheck %s -check-prefix CHECK-INVALID + +// CHECK-16: "-preferred-function-alignment" "4" +// CHECK-INVALID: invalid integral value '3' in '-fpreferred-function-alignment=3' `````````` </details> https://github.com/llvm/llvm-project/pull/155528 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
