[flang-commits] [clang] [flang] [Flang] [Driver] Add -fplt and -fno-plt options (PR #235622)
via flang-commits
flang-commits at lists.llvm.org
Mon Oct 26 00:11:01 PDT 2026
https://github.com/shivaramaarao created https://github.com/llvm/llvm-project/pull/235622
The option is supported in clang and not in flang. This commit adds this support. -fno-plt makes external calls use GOT indirection instead of the PLT. The driver forwards it only for ELF x86 and AArch64, and the default remains PLT.
>From 4512e0804b7ba1831002f0e56507b6a0d1a85834 Mon Sep 17 00:00:00 2001
From: Shivarama Rao <shivarama.rao at amd.com>
Date: Mon, 26 Oct 2026 12:05:52 +0530
Subject: [PATCH] [Flang] [Driver] Add -fplt and -fno-plt options
The option is supported in clang and not in flang. This commit adds this
support. -fno-plt makes external calls use GOT indirection instead of the PLT.
The driver forwards it only for ELF x86 and AArch64, and the default
remains PLT.
---
clang/include/clang/Options/Options.td | 4 +-
clang/lib/Driver/ToolChains/Flang.cpp | 4 ++
flang/docs/ReleaseNotes.md | 4 ++
.../include/flang/Frontend/CodeGenOptions.def | 1 +
flang/lib/Frontend/CompilerInvocation.cpp | 5 +++
flang/lib/Frontend/FrontendActions.cpp | 12 ++++++
flang/test/Driver/fno-plt.f90 | 37 +++++++++++++++++++
7 files changed, 65 insertions(+), 2 deletions(-)
create mode 100644 flang/test/Driver/fno-plt.f90
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index b760c3a1213460..98e6700082e0e1 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -4516,9 +4516,9 @@ def fno_direct_access_external_data : Flag<["-"], "fno-direct-access-external-da
HelpText<"Use GOT indirection to reference external data symbols">;
defm plt : BoolFOption<"plt",
CodeGenOpts<"NoPLT">, DefaultFalse,
- NegFlag<SetTrue, [], [ClangOption, CC1Option],
+ NegFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option],
"Use GOT indirection instead of PLT to make external function calls (x86 only)">,
- PosFlag<SetFalse>>;
+ PosFlag<SetFalse, [], [ClangOption, CC1Option, FlangOption, FC1Option]>>;
defm ropi : BoolFOption<"ropi",
LangOpts<"ROPI">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, FlangOption, CC1Option],
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 94b092e711be64..a4e0ed589b53e9 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -398,6 +398,10 @@ void Flang::addCodegenOptions(const ArgList &Args,
options::OPT_fno_optimize_sibling_calls);
const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
+ // Only ELF x86 and AArch64 use -fno-plt. The default is PLT,
+ // so only an explicit -fno-plt (last flag wins) is forwarded.
+ if (Triple.isOSBinFormatELF() && (Triple.isAArch64() || Triple.isX86()))
+ Args.addOptOutFlag(CmdArgs, options::OPT_fplt, options::OPT_fno_plt);
addSeparateSectionFlags(Triple, Args, CmdArgs);
if (Args.hasArg(options::OPT_fcoarray))
diff --git a/flang/docs/ReleaseNotes.md b/flang/docs/ReleaseNotes.md
index 147b15106b9146..b0e1624dcdeba3 100644
--- a/flang/docs/ReleaseNotes.md
+++ b/flang/docs/ReleaseNotes.md
@@ -163,6 +163,10 @@ page](https://llvm.org/releases/).
equal the array's declared leading extent, so that the common case has a
constant trip count.
+- Added `-fplt` and `-fno-plt`. `-fno-plt` makes external function
+ calls use GOT indirection instead of the PLT. The driver forwards
+ it for ELF x86 and AArch64. The default remains PLT.
+
## Windows Support
## Fortran Language Changes in Flang
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
index 569a6aa289ca31..44e0528783b571 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.def
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -33,6 +33,7 @@ ENUM_CODEGENOPT(ProfileUse, llvm::driver::ProfileInstrKind, 2, llvm::driver::Pro
CODEGENOPT(InstrumentFunctions, 1, 0) ///< Set when -finstrument_functions is
///< enabled on the compile step.
CODEGENOPT(DisableTailCalls, 1, 0) ///< Do not emit tail calls
+CODEGENOPT(NoPLT, 1, 0) ///< -fno-plt: use GOT indirection for external calls
CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 38e66aad693cbc..20564ad5abc131 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -393,6 +393,11 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
if (args.hasArg(clang::options::OPT_fno_optimize_sibling_calls))
opts.DisableTailCalls = 1;
+ // -fplt / -fno-plt. The driver forwards only -fno-plt, and only for ELF
+ // x86 and AArch64. Last flag wins if both reach the frontend.
+ opts.NoPLT = args.hasFlag(clang::options::OPT_fno_plt,
+ clang::options::OPT_fplt, /*Default=*/false);
+
// -fno-integrated-as: emit GNU Assembler compatible assembly.
if (!args.hasFlag(clang::options::OPT_fintegrated_as,
clang::options::OPT_fno_integrated_as, true))
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 9191f22b7024e8..0dd2d1dbafcee7 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -1438,6 +1438,18 @@ void CodeGenAction::executeAction() {
llvmModule->setTargetTriple(theTriple);
llvmModule->setDataLayout(theTriple.computeDataLayout(targetOpts.abi));
+ // -fno-plt: external calls use the GOT instead of the PLT. The module
+ // requests GOT for compiler-rt, and declarations that are not defined in
+ // this translation unit are marked nonlazybind.
+ if (codeGenOpts.NoPLT) {
+ llvmModule->setRtLibUseGOT();
+ for (llvm::Function &func : *llvmModule) {
+ if (!func.isDeclaration() || func.isIntrinsic())
+ continue;
+ func.addFnAttr(llvm::Attribute::NonLazyBind);
+ }
+ }
+
// Link in builtin bitcode libraries
if (!codeGenOpts.BuiltinBCLibs.empty())
linkBuiltinBCLibs();
diff --git a/flang/test/Driver/fno-plt.f90 b/flang/test/Driver/fno-plt.f90
new file mode 100644
index 00000000000000..1e2503f41ce013
--- /dev/null
+++ b/flang/test/Driver/fno-plt.f90
@@ -0,0 +1,37 @@
+! Test -f[no-]plt.
+! The driver forwards -fno-plt only for ELF x86 and AArch64. The default is
+! PLT, so -fplt is not forwarded. Other targets warn that the flag is unused.
+! In codegen, -fno-plt marks external procedures nonlazybind and requests GOT
+! for compiler-rt. A procedure defined in this file is left unchanged.
+! The default, and -fplt after -fno-plt, do neither.
+
+! RUN: %flang -### --target=x86_64-unknown-linux-gnu -fno-plt %s 2>&1 | FileCheck %s --check-prefixes=FC1,DRIVER-NOPLT
+! RUN: %flang -### --target=aarch64-unknown-linux-gnu -fno-plt %s 2>&1 | FileCheck %s --check-prefixes=FC1,DRIVER-NOPLT
+! RUN: %flang -### --target=x86_64-unknown-linux-gnu -fplt -fno-plt %s 2>&1 | FileCheck %s --check-prefixes=FC1,DRIVER-NOPLT
+! RUN: %flang -### --target=x86_64-unknown-linux-gnu %s 2>&1 | FileCheck %s --check-prefixes=FC1,DRIVER-PLT
+! RUN: %flang -### --target=x86_64-unknown-linux-gnu -fplt %s 2>&1 | FileCheck %s --check-prefixes=FC1,DRIVER-PLT
+! RUN: %flang -### --target=x86_64-unknown-linux-gnu -fno-plt -fplt %s 2>&1 | FileCheck %s --check-prefixes=FC1,DRIVER-PLT
+! RUN: %flang -### --target=powerpc64le-unknown-linux-gnu -fno-plt %s 2>&1 | FileCheck %s --check-prefixes=UNUSED,DRIVER-PLT
+! RUN: %flang -### --target=aarch64-unknown-windows-msvc -fno-plt %s 2>&1 | FileCheck %s --check-prefixes=UNUSED,DRIVER-PLT
+! RUN: %flang -### --target=x86_64-unknown-windows-msvc -fno-plt %s 2>&1 | FileCheck %s --check-prefixes=UNUSED,DRIVER-PLT
+
+! RUN: %flang_fc1 -emit-llvm -fno-plt -o - %s | FileCheck %s --check-prefix=IR-NOPLT
+! RUN: %flang_fc1 -emit-llvm -o - %s | FileCheck %s --check-prefix=IR-PLT
+! RUN: %flang_fc1 -emit-llvm -fno-plt -fplt -o - %s | FileCheck %s --check-prefix=IR-PLT
+
+subroutine test
+ call ext
+end subroutine
+
+! FC1: "-fc1"
+! DRIVER-NOPLT-SAME: "-fno-plt"
+! DRIVER-PLT-NOT: "-fno-plt"
+! UNUSED: warning: argument unused during compilation: '-fno-plt'
+! UNUSED-NOT: "-fno-plt"
+
+! IR-NOPLT: define void @test_()
+! IR-NOPLT: declare void @ext_() #[[ATTR:[0-9]+]]
+! IR-NOPLT: attributes #[[ATTR]] = { nonlazybind }
+! IR-NOPLT: !"RtLibUseGOT"
+! IR-PLT-NOT: nonlazybind
+! IR-PLT-NOT: RtLibUseGOT
More information about the flang-commits
mailing list