Skip to content

Commit 8da8ff8

Browse files
authored
[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
1 parent 2181181 commit 8da8ff8

File tree

6 files changed

+44
-2
lines changed

6 files changed

+44
-2
lines changed

clang/lib/Driver/ToolChains/Flang.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,18 @@ void Flang::AddPPCTargetArgs(const ArgList &Args,
261261

262262
void Flang::AddRISCVTargetArgs(const ArgList &Args,
263263
ArgStringList &CmdArgs) const {
264+
const Driver &D = getToolChain().getDriver();
264265
const llvm::Triple &Triple = getToolChain().getTriple();
266+
267+
StringRef ABIName = riscv::getRISCVABI(Args, Triple);
268+
if (ABIName == "lp64" || ABIName == "lp64f" || ABIName == "lp64d")
269+
CmdArgs.push_back(Args.MakeArgString("-mabi=" + ABIName));
270+
else
271+
D.Diag(diag::err_drv_unsupported_option_argument) << "-mabi=" << ABIName;
272+
265273
// Handle -mrvv-vector-bits=<bits>
266274
if (Arg *A = Args.getLastArg(options::OPT_mrvv_vector_bits_EQ)) {
267275
StringRef Val = A->getValue();
268-
const Driver &D = getToolChain().getDriver();
269276

270277
// Get minimum VLen from march.
271278
unsigned MinVLen = 0;

flang/include/flang/Frontend/TargetOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ class TargetOptions {
3535
/// If given, the name of the target CPU to tune code for.
3636
std::string cpuToTuneFor;
3737

38+
/// If given, the name of the target ABI to use.
39+
std::string abi;
40+
3841
/// The list of target specific features to enable or disable, as written on
3942
/// the command line.
4043
std::vector<std::string> featuresAsWritten;

flang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ static void parseTargetArgs(TargetOptions &opts, llvm::opt::ArgList &args) {
464464

465465
if (const llvm::opt::Arg *a =
466466
args.getLastArg(clang::driver::options::OPT_mabi_EQ)) {
467+
opts.abi = a->getValue();
467468
llvm::StringRef V = a->getValue();
468469
if (V == "vec-extabi") {
469470
opts.EnableAIXExtendedAltivecABI = true;

flang/lib/Frontend/FrontendActions.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -920,16 +920,23 @@ void CodeGenAction::generateLLVMIR() {
920920
static_cast<llvm::PIELevel::Level>(opts.PICLevel));
921921
}
922922

923+
const TargetOptions &targetOpts = ci.getInvocation().getTargetOpts();
924+
const llvm::Triple triple(targetOpts.triple);
925+
923926
// Set mcmodel level LLVM module flags
924927
std::optional<llvm::CodeModel::Model> cm = getCodeModel(opts.CodeModel);
925928
if (cm.has_value()) {
926-
const llvm::Triple triple(ci.getInvocation().getTargetOpts().triple);
927929
llvmModule->setCodeModel(*cm);
928930
if ((cm == llvm::CodeModel::Medium || cm == llvm::CodeModel::Large) &&
929931
triple.getArch() == llvm::Triple::x86_64) {
930932
llvmModule->setLargeDataThreshold(opts.LargeDataThreshold);
931933
}
932934
}
935+
936+
if (triple.isRISCV() && !targetOpts.abi.empty())
937+
llvmModule->addModuleFlag(
938+
llvm::Module::Error, "target-abi",
939+
llvm::MDString::get(llvmModule->getContext(), targetOpts.abi));
933940
}
934941

935942
static std::unique_ptr<llvm::raw_pwrite_stream>

flang/test/Driver/mabi-riscv.f90

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
! RUN: not %flang -c --target=riscv64-unknown-linux -mabi=ilp32 %s -### 2>&1 | FileCheck --check-prefix=INVALID1 %s
2+
! RUN: not %flang -c --target=riscv64-unknown-linux -mabi=lp64e %s -### 2>&1 | FileCheck --check-prefix=INVALID2 %s
3+
! RUN: %flang -c --target=riscv64-unknown-linux -mabi=lp64 %s -### 2>&1 | FileCheck --check-prefix=ABI1 %s
4+
! RUN: %flang -c --target=riscv64-unknown-linux -mabi=lp64f %s -### 2>&1 | FileCheck --check-prefix=ABI2 %s
5+
! RUN: %flang -c --target=riscv64-unknown-linux -mabi=lp64d %s -### 2>&1 | FileCheck --check-prefix=ABI3 %s
6+
! RUN: %flang -c --target=riscv64-unknown-linux %s -### 2>&1 | FileCheck --check-prefix=ABI3 %s
7+
8+
! INVALID1: error: unsupported argument 'ilp32' to option '-mabi='
9+
! INVALID2: error: unsupported argument 'lp64e' to option '-mabi='
10+
11+
! ABI1: "-mabi=lp64"
12+
! ABI2: "-mabi=lp64f"
13+
! ABI3: "-mabi=lp64d"
14+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
! REQUIRES: riscv-registered-target
2+
! RUN: %flang_fc1 -triple riscv64-none-linux-gnu -mabi=lp64 -emit-llvm -o - %s | FileCheck %s --check-prefix=LP64
3+
! RUN: %flang_fc1 -triple riscv64-none-linux-gnu -mabi=lp64f -emit-llvm -o - %s | FileCheck %s --check-prefix=LP64F
4+
! RUN: %flang_fc1 -triple riscv64-none-linux-gnu -mabi=lp64d -emit-llvm -o - %s | FileCheck %s --check-prefix=LP64D
5+
6+
! LP64: !{{[0-9]+}} = !{i32 1, !"target-abi", !"lp64"}
7+
! LP64F: !{{[0-9]+}} = !{i32 1, !"target-abi", !"lp64f"}
8+
! LP64D: !{{[0-9]+}} = !{i32 1, !"target-abi", !"lp64d"}
9+
subroutine func
10+
end subroutine func

0 commit comments

Comments
 (0)