[clang] [Clang] Support `-falign-loops=N` for LTO (PR #181702)
Anton Sidorenko via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 16 08:54:15 PST 2026
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 <anton.sidorenko at syntacore.com>
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"
More information about the cfe-commits
mailing list