[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
This commit is contained in:
Craig Topper 2025-02-13 08:08:09 -08:00 committed by GitHub
parent 21811818d6
commit 8da8ff8768
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 44 additions and 2 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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>

View File

@ -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"

View File

@ -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