[flang-commits] [flang] [Flang] Add target-abi to CodegenSpecifics (PR #201539)
via flang-commits
flang-commits at lists.llvm.org
Thu Jun 4 02:48:41 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Philipp Rados (prados-oc)
<details>
<summary>Changes</summary>
This sets the target-abi, specified in TargetOptions on the MLIR-Module. This allows it to be used by CodegenSpecifics in the TargetRewritePass.
Currently this is only needed by RISCV64, but can also be used by other targets. This allows to reuse the logic from clang when determining the ABI, needed for patch https://github.com/llvm/llvm-project/pull/198335#discussion_r3272341234.
cc @<!-- -->jeanPerier
---
Full diff: https://github.com/llvm/llvm-project/pull/201539.diff
10 Files Affected:
- (modified) flang/include/flang/Optimizer/CodeGen/CGPasses.td (+4)
- (modified) flang/include/flang/Optimizer/CodeGen/Target.h (+13-8)
- (modified) flang/include/flang/Optimizer/Dialect/Support/FIRContext.h (+6)
- (modified) flang/lib/Lower/Bridge.cpp (+1)
- (modified) flang/lib/Optimizer/CodeGen/CodeGen.cpp (+3)
- (modified) flang/lib/Optimizer/CodeGen/Target.cpp (+42-31)
- (modified) flang/lib/Optimizer/CodeGen/TargetRewrite.cpp (+5-2)
- (modified) flang/lib/Optimizer/CodeGen/TypeConverter.cpp (+2-2)
- (modified) flang/lib/Optimizer/Dialect/Support/FIRContext.cpp (+17)
- (added) flang/test/Fir/target-rewrite-target-abi.fir (+24)
``````````diff
diff --git a/flang/include/flang/Optimizer/CodeGen/CGPasses.td b/flang/include/flang/Optimizer/CodeGen/CGPasses.td
index 168463f1514a7..ace3dadc590c8 100644
--- a/flang/include/flang/Optimizer/CodeGen/CGPasses.td
+++ b/flang/include/flang/Optimizer/CodeGen/CGPasses.td
@@ -35,6 +35,8 @@ def FIRToLLVMLowering : Pass<"fir-to-llvm-ir", "mlir::ModuleOp"> {
"Override module's tune CPU.">,
Option<"forcedTargetFeatures", "target-features", "std::string",
/*default=*/"", "Override module's target features.">,
+ Option<"forcedTargetABI", "target-abi", "std::string", /*default=*/"",
+ "Override module's target ABI.">,
Option<"applyTBAA", "apply-tbaa", "bool", /*default=*/"false",
"Attach TBAA tags to memory accessing operations.">,
Option<"typeDescriptorsRenamedForAssembly",
@@ -91,6 +93,8 @@ def TargetRewritePass : Pass<"target-rewrite", "mlir::ModuleOp"> {
"Override module's tune CPU.">,
Option<"forcedTargetFeatures", "target-features", "std::string",
/*default=*/"", "Override module's target features.">,
+ Option<"forcedTargetABI", "target-abi", "std::string", /*default=*/"",
+ "Override module's target ABI.">,
Option<"noCharacterConversion", "no-character-conversion",
"bool", /*default=*/"false",
"Disable target-specific conversion of CHARACTER.">,
diff --git a/flang/include/flang/Optimizer/CodeGen/Target.h b/flang/include/flang/Optimizer/CodeGen/Target.h
index 54bd8c9c457a1..2a374875d31a0 100644
--- a/flang/include/flang/Optimizer/CodeGen/Target.h
+++ b/flang/include/flang/Optimizer/CodeGen/Target.h
@@ -74,30 +74,32 @@ class CodeGenSpecifics {
static std::unique_ptr<CodeGenSpecifics>
get(mlir::MLIRContext *ctx, llvm::Triple &&trp, KindMapping &&kindMap,
llvm::StringRef targetCPU, mlir::LLVM::TargetFeaturesAttr targetFeatures,
- const mlir::DataLayout &dl);
+ llvm::StringRef targetABI, const mlir::DataLayout &dl);
static std::unique_ptr<CodeGenSpecifics>
get(mlir::MLIRContext *ctx, llvm::Triple &&trp, KindMapping &&kindMap,
llvm::StringRef targetCPU, mlir::LLVM::TargetFeaturesAttr targetFeatures,
- const mlir::DataLayout &dl, llvm::StringRef tuneCPU);
+ llvm::StringRef targetABI, const mlir::DataLayout &dl,
+ llvm::StringRef tuneCPU);
static TypeAndAttr getTypeAndAttr(mlir::Type t) { return TypeAndAttr{t, {}}; }
CodeGenSpecifics(mlir::MLIRContext *ctx, llvm::Triple &&trp,
KindMapping &&kindMap, llvm::StringRef targetCPU,
mlir::LLVM::TargetFeaturesAttr targetFeatures,
- const mlir::DataLayout &dl)
+ llvm::StringRef targetABI, const mlir::DataLayout &dl)
: context{*ctx}, triple{std::move(trp)}, kindMap{std::move(kindMap)},
- targetCPU{targetCPU}, targetFeatures{targetFeatures}, dataLayout{&dl},
- tuneCPU{""} {}
+ targetCPU{targetCPU}, targetFeatures{targetFeatures},
+ targetABI{targetABI}, dataLayout{&dl}, tuneCPU{""} {}
CodeGenSpecifics(mlir::MLIRContext *ctx, llvm::Triple &&trp,
KindMapping &&kindMap, llvm::StringRef targetCPU,
mlir::LLVM::TargetFeaturesAttr targetFeatures,
- const mlir::DataLayout &dl, llvm::StringRef tuneCPU)
+ llvm::StringRef targetABI, const mlir::DataLayout &dl,
+ llvm::StringRef tuneCPU)
: context{*ctx}, triple{std::move(trp)}, kindMap{std::move(kindMap)},
- targetCPU{targetCPU}, targetFeatures{targetFeatures}, dataLayout{&dl},
- tuneCPU{tuneCPU} {}
+ targetCPU{targetCPU}, targetFeatures{targetFeatures},
+ targetABI{targetABI}, dataLayout{&dl}, tuneCPU{tuneCPU} {}
CodeGenSpecifics() = delete;
virtual ~CodeGenSpecifics() {}
@@ -183,6 +185,8 @@ class CodeGenSpecifics {
return targetFeatures;
}
+ llvm::StringRef getTargetABI() const { return targetABI; }
+
const mlir::DataLayout &getDataLayout() const {
assert(dataLayout && "dataLayout must be set");
return *dataLayout;
@@ -194,6 +198,7 @@ class CodeGenSpecifics {
KindMapping kindMap;
llvm::StringRef targetCPU;
mlir::LLVM::TargetFeaturesAttr targetFeatures;
+ llvm::StringRef targetABI;
const mlir::DataLayout *dataLayout = nullptr;
llvm::StringRef tuneCPU;
};
diff --git a/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h b/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
index 3fea111941551..79337584d6d67 100644
--- a/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
+++ b/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h
@@ -91,6 +91,12 @@ void setTargetFeatures(mlir::ModuleOp mod, llvm::StringRef features);
/// Get the target features from the Module.
mlir::LLVM::TargetFeaturesAttr getTargetFeatures(mlir::ModuleOp mod);
+/// Set the target ABI for the module.
+void setTargetABI(mlir::ModuleOp mod, llvm::StringRef abi);
+
+/// Get the target ABI string from the Module or return a null reference.
+llvm::StringRef getTargetABI(mlir::ModuleOp mod);
+
/// Set the compiler identifier for the module.
void setIdent(mlir::ModuleOp mod, llvm::StringRef ident);
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 1dfcb9980f18f..fbd448326ecdf 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -7138,6 +7138,7 @@ Fortran::lower::LoweringBridge::LoweringBridge(
fir::setAtomicFineGrainedMemory(*module, targetOpts.atomicFineGrainedMemory);
fir::setAtomicRemoteMemory(*module, targetOpts.atomicRemoteMemory);
fir::setTargetFeatures(*module, targetMachine.getTargetFeatureString());
+ fir::setTargetABI(*module, targetOpts.abi);
fir::support::setMLIRDataLayout(*module, targetMachine.createDataLayout());
fir::setIdent(*module, Fortran::common::getFlangFullVersion());
fir::setRelocationModel(*module, cgOpts.getRelocationModel());
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 6b1acba393170..ec6e31eecdcc1 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -4663,6 +4663,9 @@ class FIRToLLVMLowering
if (!forcedTargetFeatures.empty())
fir::setTargetFeatures(mod, forcedTargetFeatures);
+ if (!forcedTargetABI.empty())
+ fir::setTargetABI(mod, forcedTargetABI);
+
if (typeDescriptorsRenamedForAssembly)
options.typeDescriptorsRenamedForAssembly =
typeDescriptorsRenamedForAssembly;
diff --git a/flang/lib/Optimizer/CodeGen/Target.cpp b/flang/lib/Optimizer/CodeGen/Target.cpp
index 9b6c9be79120c..45311850e38df 100644
--- a/flang/lib/Optimizer/CodeGen/Target.cpp
+++ b/flang/lib/Optimizer/CodeGen/Target.cpp
@@ -1897,11 +1897,10 @@ struct TargetLoongArch64 : public GenericTarget<TargetLoongArch64> {
// Instantiate the overloaded target instance based on the triple value.
// TODO: Add other targets to this file as needed.
-std::unique_ptr<fir::CodeGenSpecifics>
-fir::CodeGenSpecifics::get(mlir::MLIRContext *ctx, llvm::Triple &&trp,
- KindMapping &&kindMap, llvm::StringRef targetCPU,
- mlir::LLVM::TargetFeaturesAttr targetFeatures,
- const mlir::DataLayout &dl) {
+std::unique_ptr<fir::CodeGenSpecifics> fir::CodeGenSpecifics::get(
+ mlir::MLIRContext *ctx, llvm::Triple &&trp, KindMapping &&kindMap,
+ llvm::StringRef targetCPU, mlir::LLVM::TargetFeaturesAttr targetFeatures,
+ llvm::StringRef targetABI, const mlir::DataLayout &dl) {
switch (trp.getArch()) {
default:
break;
@@ -1909,50 +1908,60 @@ fir::CodeGenSpecifics::get(mlir::MLIRContext *ctx, llvm::Triple &&trp,
if (trp.isOSWindows())
return std::make_unique<TargetI386Win>(ctx, std::move(trp),
std::move(kindMap), targetCPU,
- targetFeatures, dl);
+ targetFeatures, targetABI, dl);
else
return std::make_unique<TargetI386>(ctx, std::move(trp),
std::move(kindMap), targetCPU,
- targetFeatures, dl);
+ targetFeatures, targetABI, dl);
case llvm::Triple::ArchType::x86_64:
if (trp.isOSWindows())
return std::make_unique<TargetX86_64Win>(ctx, std::move(trp),
std::move(kindMap), targetCPU,
- targetFeatures, dl);
+ targetFeatures, targetABI, dl);
else
return std::make_unique<TargetX86_64>(ctx, std::move(trp),
std::move(kindMap), targetCPU,
- targetFeatures, dl);
+ targetFeatures, targetABI, dl);
case llvm::Triple::ArchType::aarch64:
- return std::make_unique<TargetAArch64>(
- ctx, std::move(trp), std::move(kindMap), targetCPU, targetFeatures, dl);
+ return std::make_unique<TargetAArch64>(ctx, std::move(trp),
+ std::move(kindMap), targetCPU,
+ targetFeatures, targetABI, dl);
case llvm::Triple::ArchType::ppc:
return std::make_unique<TargetPPC>(ctx, std::move(trp), std::move(kindMap),
- targetCPU, targetFeatures, dl);
+ targetCPU, targetFeatures, targetABI,
+ dl);
case llvm::Triple::ArchType::ppc64:
- return std::make_unique<TargetPPC64>(
- ctx, std::move(trp), std::move(kindMap), targetCPU, targetFeatures, dl);
+ return std::make_unique<TargetPPC64>(ctx, std::move(trp),
+ std::move(kindMap), targetCPU,
+ targetFeatures, targetABI, dl);
case llvm::Triple::ArchType::ppc64le:
- return std::make_unique<TargetPPC64le>(
- ctx, std::move(trp), std::move(kindMap), targetCPU, targetFeatures, dl);
+ return std::make_unique<TargetPPC64le>(ctx, std::move(trp),
+ std::move(kindMap), targetCPU,
+ targetFeatures, targetABI, dl);
case llvm::Triple::ArchType::sparc:
- return std::make_unique<TargetSparc>(
- ctx, std::move(trp), std::move(kindMap), targetCPU, targetFeatures, dl);
+ return std::make_unique<TargetSparc>(ctx, std::move(trp),
+ std::move(kindMap), targetCPU,
+ targetFeatures, targetABI, dl);
case llvm::Triple::ArchType::sparcv9:
- return std::make_unique<TargetSparcV9>(
- ctx, std::move(trp), std::move(kindMap), targetCPU, targetFeatures, dl);
+ return std::make_unique<TargetSparcV9>(ctx, std::move(trp),
+ std::move(kindMap), targetCPU,
+ targetFeatures, targetABI, dl);
case llvm::Triple::ArchType::riscv64:
- return std::make_unique<TargetRISCV64>(
- ctx, std::move(trp), std::move(kindMap), targetCPU, targetFeatures, dl);
+ return std::make_unique<TargetRISCV64>(ctx, std::move(trp),
+ std::move(kindMap), targetCPU,
+ targetFeatures, targetABI, dl);
case llvm::Triple::ArchType::amdgcn:
- return std::make_unique<TargetAMDGPU>(
- ctx, std::move(trp), std::move(kindMap), targetCPU, targetFeatures, dl);
+ return std::make_unique<TargetAMDGPU>(ctx, std::move(trp),
+ std::move(kindMap), targetCPU,
+ targetFeatures, targetABI, dl);
case llvm::Triple::ArchType::nvptx64:
- return std::make_unique<TargetNVPTX>(
- ctx, std::move(trp), std::move(kindMap), targetCPU, targetFeatures, dl);
+ return std::make_unique<TargetNVPTX>(ctx, std::move(trp),
+ std::move(kindMap), targetCPU,
+ targetFeatures, targetABI, dl);
case llvm::Triple::ArchType::loongarch64:
- return std::make_unique<TargetLoongArch64>(
- ctx, std::move(trp), std::move(kindMap), targetCPU, targetFeatures, dl);
+ return std::make_unique<TargetLoongArch64>(ctx, std::move(trp),
+ std::move(kindMap), targetCPU,
+ targetFeatures, targetABI, dl);
}
TODO(mlir::UnknownLoc::get(ctx), "target not implemented");
}
@@ -1960,9 +1969,11 @@ fir::CodeGenSpecifics::get(mlir::MLIRContext *ctx, llvm::Triple &&trp,
std::unique_ptr<fir::CodeGenSpecifics> fir::CodeGenSpecifics::get(
mlir::MLIRContext *ctx, llvm::Triple &&trp, KindMapping &&kindMap,
llvm::StringRef targetCPU, mlir::LLVM::TargetFeaturesAttr targetFeatures,
- const mlir::DataLayout &dl, llvm::StringRef tuneCPU) {
- std::unique_ptr<fir::CodeGenSpecifics> CGS = fir::CodeGenSpecifics::get(
- ctx, std::move(trp), std::move(kindMap), targetCPU, targetFeatures, dl);
+ llvm::StringRef targetABI, const mlir::DataLayout &dl,
+ llvm::StringRef tuneCPU) {
+ std::unique_ptr<fir::CodeGenSpecifics> CGS =
+ fir::CodeGenSpecifics::get(ctx, std::move(trp), std::move(kindMap),
+ targetCPU, targetFeatures, targetABI, dl);
CGS->tuneCPU = tuneCPU;
return CGS;
diff --git a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
index a4847288459b4..3701e5abff6df 100644
--- a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
+++ b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
@@ -104,6 +104,9 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase<TargetRewrite> {
if (!forcedTargetFeatures.empty())
fir::setTargetFeatures(mod, forcedTargetFeatures);
+ if (!forcedTargetABI.empty())
+ fir::setTargetABI(mod, forcedTargetABI);
+
// TargetRewrite will require querying the type storage sizes, if it was
// not set already, create a DataLayoutSpec for the ModuleOp now.
std::optional<mlir::DataLayout> dl =
@@ -118,8 +121,8 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase<TargetRewrite> {
auto specifics = fir::CodeGenSpecifics::get(
mod.getContext(), fir::getTargetTriple(mod), fir::getKindMapping(mod),
- fir::getTargetCPU(mod), fir::getTargetFeatures(mod), *dl,
- fir::getTuneCPU(mod));
+ fir::getTargetCPU(mod), fir::getTargetFeatures(mod),
+ fir::getTargetABI(mod), *dl, fir::getTuneCPU(mod));
setMembers(specifics.get(), &rewriter, &*dl);
diff --git a/flang/lib/Optimizer/CodeGen/TypeConverter.cpp b/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
index 2fca4111e0980..a045828fae154 100644
--- a/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
+++ b/flang/lib/Optimizer/CodeGen/TypeConverter.cpp
@@ -70,8 +70,8 @@ LLVMTypeConverter::LLVMTypeConverter(mlir::ModuleOp module, bool applyTBAA,
kindMapping(getKindMapping(module)),
specifics(CodeGenSpecifics::get(
module.getContext(), getTargetTriple(module), getKindMapping(module),
- getTargetCPU(module), getTargetFeatures(module), dl,
- getTuneCPU(module))),
+ getTargetCPU(module), getTargetFeatures(module), getTargetABI(module),
+ dl, getTuneCPU(module))),
tbaaBuilder(std::make_unique<TBAABuilder>(module->getContext(), applyTBAA,
forceUnifiedTBAATree)),
dataLayout{&dl} {
diff --git a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
index 2dfc1e845b573..16757f934c8d7 100644
--- a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
+++ b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp
@@ -146,6 +146,23 @@ llvm::StringRef fir::getTuneCPU(mlir::ModuleOp mod) {
return {};
}
+static constexpr const char *targetABIName = "fir.target_abi";
+
+void fir::setTargetABI(mlir::ModuleOp mod, llvm::StringRef abi) {
+ if (abi.empty())
+ return;
+
+ auto *ctx = mod.getContext();
+ mod->setAttr(targetABIName, mlir::StringAttr::get(ctx, abi));
+}
+
+mlir::StringRef fir::getTargetABI(mlir::ModuleOp mod) {
+ if (auto attr = mod->getAttrOfType<mlir::StringAttr>(targetABIName))
+ return attr.getValue();
+
+ return {};
+}
+
static constexpr const char *targetFeaturesName = "fir.target_features";
void fir::setTargetFeatures(mlir::ModuleOp mod, llvm::StringRef features) {
diff --git a/flang/test/Fir/target-rewrite-target-abi.fir b/flang/test/Fir/target-rewrite-target-abi.fir
new file mode 100644
index 0000000000000..888a8d49fce31
--- /dev/null
+++ b/flang/test/Fir/target-rewrite-target-abi.fir
@@ -0,0 +1,24 @@
+// RUN: fir-opt --target-rewrite %s | FileCheck %s --check-prefixes=DEFAULT
+// RUN: fir-opt --target-rewrite="target-abi=lp64d" %s | FileCheck %s --check-prefixes=LP64D
+// RUN: fir-opt --target-rewrite="target-abi=lp64f" %s | FileCheck %s --check-prefixes=LP64F
+// RUN: fir-opt --target-rewrite="target=riscv64-unknown-linux-gnu target-abi=lp64" %s | FileCheck %s --check-prefixes=LINUX
+
+// Currently only RISCV64 uses the target-abi option.
+
+// DEFAULT: module attributes {
+// DEFAULT-SAME: fir.target_abi = "lp64"
+
+// LP64D: module attributes {
+// LP64D-SAME: fir.target_abi = "lp64d"
+
+// LP64F: module attributes {
+// LP64F-SAME: fir.target_abi = "lp64f"
+
+// LINUX: module attributes {
+// LINUX-SAME: fir.target_abi = "lp64"
+
+module attributes {fir.target_abi = "lp64"} {
+ func.func @dummyfunc() -> () {
+ return
+ }
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/201539
More information about the flang-commits
mailing list