https://github.com/asi-sc created https://github.com/llvm/llvm-project/pull/181702
This commit adds forwarding of the option to LTO build. This behavior is aligned with GCC. Without it users have to use `-Wl,-mllvm,--align-loops=N` and from my practice they usually forget/are not aware of it. >From 6b30c746c24c8c870a92d7872efe4697d789e6ff Mon Sep 17 00:00:00 2001 From: Anton Sidorenko <[email protected]> Date: Wed, 11 Feb 2026 12:25:25 +0000 Subject: [PATCH] [Clang] Support `-falign-loops=N` for LTO This commit adds forwarding of the option to LTO build. This behavior is aligned with GCC. Without it users have to use `-Wl,-mllvm,--align-loops=N` and from my practice they usually forget/are not aware of it. --- clang/include/clang/Driver/CommonArgs.h | 2 ++ clang/lib/Driver/ToolChains/Clang.cpp | 19 ++++------------ clang/lib/Driver/ToolChains/CommonArgs.cpp | 26 ++++++++++++++++++++++ clang/test/Driver/falign-loops.c | 11 +++++++++ 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/clang/include/clang/Driver/CommonArgs.h b/clang/include/clang/Driver/CommonArgs.h index a895579be7419..9f370f9841632 100644 --- a/clang/include/clang/Driver/CommonArgs.h +++ b/clang/include/clang/Driver/CommonArgs.h @@ -93,6 +93,8 @@ bool getStaticPIE(const llvm::opt::ArgList &Args, const ToolChain &TC); unsigned ParseFunctionAlignment(const ToolChain &TC, const llvm::opt::ArgList &Args); +unsigned ParseLoopAlignment(const Driver &D, const llvm::opt::ArgList &Args); + void addDebugInfoKind(llvm::opt::ArgStringList &CmdArgs, llvm::codegenoptions::DebugInfoKind DebugInfoKind); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index c16aa33f29ebb..63a917efdc7f5 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5492,21 +5492,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(std::to_string(FunctionAlignment))); } - // 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)) { - unsigned Value = 0; - if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 65536) - TC.getDriver().Diag(diag::err_drv_invalid_int_value) - << A->getAsString(Args) << A->getValue(); - else if (Value & (Value - 1)) - TC.getDriver().Diag(diag::err_drv_alignment_not_power_of_two) - << A->getAsString(Args) << A->getValue(); - // Treat =0 as unspecified (use the target preference). - if (Value) - CmdArgs.push_back(Args.MakeArgString("-falign-loops=" + - Twine(std::min(Value, 65536u)))); - } + unsigned LoopAlignment = ParseLoopAlignment(TC.getDriver(), Args); + if (LoopAlignment) + CmdArgs.push_back( + Args.MakeArgString("-falign-loops=" + Twine(LoopAlignment))); if (Triple.isOSzOS()) { // On z/OS some of the system header feature macros need to diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 8bb271d27a3c4..12665a13c3c68 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1393,6 +1393,11 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args, Args.MakeArgString(Twine(PluginOptPrefix) + "-time-passes")); addDTLTOOptions(ToolChain, Args, CmdArgs); + + unsigned LoopAlignment = ParseLoopAlignment(D, Args); + if (LoopAlignment) + CmdArgs.push_back(Args.MakeArgString( + Twine(PluginOptPrefix) + "-align-loops=" + Twine(LoopAlignment))); } void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC, @@ -2226,6 +2231,27 @@ unsigned tools::ParseFunctionAlignment(const ToolChain &TC, return Value ? llvm::Log2_32_Ceil(std::min(Value, 65536u)) : Value; } +// Parse `-falign-loops`. Return `0` if the target preference should be used. +unsigned tools::ParseLoopAlignment(const Driver &D, const ArgList &Args) { + const Arg *A = Args.getLastArg(options::OPT_falign_loops_EQ); + if (!A) + return 0; + unsigned Value = 0; + if (StringRef(A->getValue()).getAsInteger(10, Value) || Value > 65536) { + D.Diag(diag::err_drv_invalid_int_value) + << A->getAsString(Args) << A->getValue(); + return 0; + } + // We support -falign-loops=N where N is a power of 2. GCC supports more + // forms. + if (Value & (Value - 1)) { + D.Diag(diag::err_drv_alignment_not_power_of_two) + << A->getAsString(Args) << A->getValue(); + return 0; + } + return Value; +} + void tools::addDebugInfoKind( ArgStringList &CmdArgs, llvm::codegenoptions::DebugInfoKind DebugInfoKind) { switch (DebugInfoKind) { diff --git a/clang/test/Driver/falign-loops.c b/clang/test/Driver/falign-loops.c index 4526ee12f3221..8a424be6fd214 100644 --- a/clang/test/Driver/falign-loops.c +++ b/clang/test/Driver/falign-loops.c @@ -7,6 +7,8 @@ // RUN: %clang -### -falign-loops=65536 %s 2>&1 | FileCheck %s --check-prefix=CHECK_65536 // RUN: not %clang -### -falign-loops=65537 %s 2>&1 | FileCheck %s --check-prefix=CHECK_65537 // RUN: not %clang -### -falign-loops=a %s 2>&1 | FileCheck %s --check-prefix=CHECK_ERR_A +// RUN: %clang -### -falign-loops=2 -fuse-ld=lld %s 2>&1 | FileCheck --check-prefixes=CC1,OBJ %s +// RUN: %clang -### -falign-loops=2 -fuse-ld=lld -flto %s 2>&1 | FileCheck --check-prefixes=CC1,LTO %s // CHECK_NO-NOT: "-falign-loops= // CHECK_1: "-falign-loops=1" @@ -15,3 +17,12 @@ // CHECK_65536: "-falign-loops=65536" // CHECK_65537: error: invalid integral value '65537' in '-falign-loops=65537' // CHECK_ERR_A: error: invalid integral value 'a' in '-falign-loops=a' + +// CC1: -cc1 +// CC1: "-falign-loops=2" + +// OBJ: lld +// OBJ-NOT: -align-loops=2 + +// LTO: lld +// LTO: "-plugin-opt=-align-loops=2" _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
