diff options
author | Craig Topper <craig.topper@sifive.com> | 2025-02-13 08:08:09 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-13 08:08:09 -0800 |
commit | 8da8ff8768bc0115f21d7d8fe8d47872190f8de1 (patch) | |
tree | 1bba09ad0b5ff23b0679410e2291c244652d5b36 | |
parent | 21811818d6c1a50051032fdb2d350ffe89e1421a (diff) | |
download | llvm-8da8ff8768bc0115f21d7d8fe8d47872190f8de1.zip llvm-8da8ff8768bc0115f21d7d8fe8d47872190f8de1.tar.gz llvm-8da8ff8768bc0115f21d7d8fe8d47872190f8de1.tar.bz2 |
[flang][RISCV] Add target-abi ModuleFlag. (#126188)
This is needed to generate proper ABI flags in the ELF header for LTO
builds. If these flags aren't set correctly, we can't link with objects
that were built with the correct flags.
For non-LTO builds the mcpu/mattr in the TargetMachine will cause the
backend to infer an ABI. For LTO builds the mcpu/mattr aren't set.
I've only added lp64, lp64f, and lp64d ABIs. ilp32* requires riscv32
which is not yet supported in flang. lp64e requires a different
DataLayout string and would need additional plumbing.
Fixes #115679
-rw-r--r-- | clang/lib/Driver/ToolChains/Flang.cpp | 9 | ||||
-rw-r--r-- | flang/include/flang/Frontend/TargetOptions.h | 3 | ||||
-rw-r--r-- | flang/lib/Frontend/CompilerInvocation.cpp | 1 | ||||
-rw-r--r-- | flang/lib/Frontend/FrontendActions.cpp | 9 | ||||
-rw-r--r-- | flang/test/Driver/mabi-riscv.f90 | 14 | ||||
-rw-r--r-- | flang/test/Lower/RISCV/riscv-target-abi.f90 | 10 |
6 files changed, 44 insertions, 2 deletions
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 2b7ce6d..9ad795e 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -261,11 +261,18 @@ void Flang::AddPPCTargetArgs(const ArgList &Args, void Flang::AddRISCVTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { + const Driver &D = getToolChain().getDriver(); const llvm::Triple &Triple = getToolChain().getTriple(); + + StringRef ABIName = riscv::getRISCVABI(Args, Triple); + if (ABIName == "lp64" || ABIName == "lp64f" || ABIName == "lp64d") + CmdArgs.push_back(Args.MakeArgString("-mabi=" + ABIName)); + else + D.Diag(diag::err_drv_unsupported_option_argument) << "-mabi=" << ABIName; + // Handle -mrvv-vector-bits=<bits> if (Arg *A = Args.getLastArg(options::OPT_mrvv_vector_bits_EQ)) { StringRef Val = A->getValue(); - const Driver &D = getToolChain().getDriver(); // Get minimum VLen from march. unsigned MinVLen = 0; diff --git a/flang/include/flang/Frontend/TargetOptions.h b/flang/include/flang/Frontend/TargetOptions.h index 01c8780..4a85464 100644 --- a/flang/include/flang/Frontend/TargetOptions.h +++ b/flang/include/flang/Frontend/TargetOptions.h @@ -35,6 +35,9 @@ public: /// If given, the name of the target CPU to tune code for. std::string cpuToTuneFor; + /// If given, the name of the target ABI to use. + std::string abi; + /// The list of target specific features to enable or disable, as written on /// the command line. std::vector<std::string> featuresAsWritten; diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index d4d3971..f3d9432 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -464,6 +464,7 @@ static void parseTargetArgs(TargetOptions &opts, llvm::opt::ArgList &args) { if (const llvm::opt::Arg *a = args.getLastArg(clang::driver::options::OPT_mabi_EQ)) { + opts.abi = a->getValue(); llvm::StringRef V = a->getValue(); if (V == "vec-extabi") { opts.EnableAIXExtendedAltivecABI = true; diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index 622848e..763c810 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -920,16 +920,23 @@ void CodeGenAction::generateLLVMIR() { static_cast<llvm::PIELevel::Level>(opts.PICLevel)); } + const TargetOptions &targetOpts = ci.getInvocation().getTargetOpts(); + const llvm::Triple triple(targetOpts.triple); + // Set mcmodel level LLVM module flags std::optional<llvm::CodeModel::Model> cm = getCodeModel(opts.CodeModel); if (cm.has_value()) { - const llvm::Triple triple(ci.getInvocation().getTargetOpts().triple); llvmModule->setCodeModel(*cm); if ((cm == llvm::CodeModel::Medium || cm == llvm::CodeModel::Large) && triple.getArch() == llvm::Triple::x86_64) { llvmModule->setLargeDataThreshold(opts.LargeDataThreshold); } } + + if (triple.isRISCV() && !targetOpts.abi.empty()) + llvmModule->addModuleFlag( + llvm::Module::Error, "target-abi", + llvm::MDString::get(llvmModule->getContext(), targetOpts.abi)); } static std::unique_ptr<llvm::raw_pwrite_stream> diff --git a/flang/test/Driver/mabi-riscv.f90 b/flang/test/Driver/mabi-riscv.f90 new file mode 100644 index 0000000..355ea9f --- /dev/null +++ b/flang/test/Driver/mabi-riscv.f90 @@ -0,0 +1,14 @@ +! RUN: not %flang -c --target=riscv64-unknown-linux -mabi=ilp32 %s -### 2>&1 | FileCheck --check-prefix=INVALID1 %s +! RUN: not %flang -c --target=riscv64-unknown-linux -mabi=lp64e %s -### 2>&1 | FileCheck --check-prefix=INVALID2 %s +! RUN: %flang -c --target=riscv64-unknown-linux -mabi=lp64 %s -### 2>&1 | FileCheck --check-prefix=ABI1 %s +! RUN: %flang -c --target=riscv64-unknown-linux -mabi=lp64f %s -### 2>&1 | FileCheck --check-prefix=ABI2 %s +! RUN: %flang -c --target=riscv64-unknown-linux -mabi=lp64d %s -### 2>&1 | FileCheck --check-prefix=ABI3 %s +! RUN: %flang -c --target=riscv64-unknown-linux %s -### 2>&1 | FileCheck --check-prefix=ABI3 %s + +! INVALID1: error: unsupported argument 'ilp32' to option '-mabi=' +! INVALID2: error: unsupported argument 'lp64e' to option '-mabi=' + +! ABI1: "-mabi=lp64" +! ABI2: "-mabi=lp64f" +! ABI3: "-mabi=lp64d" + diff --git a/flang/test/Lower/RISCV/riscv-target-abi.f90 b/flang/test/Lower/RISCV/riscv-target-abi.f90 new file mode 100644 index 0000000..1077655 --- /dev/null +++ b/flang/test/Lower/RISCV/riscv-target-abi.f90 @@ -0,0 +1,10 @@ +! REQUIRES: riscv-registered-target +! RUN: %flang_fc1 -triple riscv64-none-linux-gnu -mabi=lp64 -emit-llvm -o - %s | FileCheck %s --check-prefix=LP64 +! RUN: %flang_fc1 -triple riscv64-none-linux-gnu -mabi=lp64f -emit-llvm -o - %s | FileCheck %s --check-prefix=LP64F +! RUN: %flang_fc1 -triple riscv64-none-linux-gnu -mabi=lp64d -emit-llvm -o - %s | FileCheck %s --check-prefix=LP64D + +! LP64: !{{[0-9]+}} = !{i32 1, !"target-abi", !"lp64"} +! LP64F: !{{[0-9]+}} = !{i32 1, !"target-abi", !"lp64f"} +! LP64D: !{{[0-9]+}} = !{i32 1, !"target-abi", !"lp64d"} +subroutine func +end subroutine func |