https://github.com/shivaramaarao updated https://github.com/llvm/llvm-project/pull/235622
>From 6da1d955d1d66fff3fa022783182f1a0e412b270 Mon Sep 17 00:00:00 2001 From: Shivarama Rao <[email protected]> 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 | 39 +++++++++++++++++++ 7 files changed, 67 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..52b3826640ee47 --- /dev/null +++ b/flang/test/Driver/fno-plt.f90 @@ -0,0 +1,39 @@ +! 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 + +! nonlazybind and the RtLibUseGOT module flag are applied to the LLVM module +! after FIR is translated, so -emit-hlfir and -emit-fir cannot observe them. +! 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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
