[flang-commits] [flang] [Flang] Add target-abi to CodegenSpecifics (PR #201539)
Philipp Rados via flang-commits
flang-commits at lists.llvm.org
Thu Jun 11 03:39:30 PDT 2026
https://github.com/prados-oc updated https://github.com/llvm/llvm-project/pull/201539
>From 0c69d0c179139fdb1065ac601440b162a0045c44 Mon Sep 17 00:00:00 2001
From: Philipp Rados <philipp.rados at openchip.com>
Date: Mon, 1 Jun 2026 14:28:19 +0200
Subject: [PATCH 1/3] [Flang] Add target-abi to CodegenSpecifics
---
.../flang/Optimizer/CodeGen/CGPasses.td | 4 +
.../include/flang/Optimizer/CodeGen/Target.h | 21 ++++--
.../Optimizer/Dialect/Support/FIRContext.h | 6 ++
flang/lib/Lower/Bridge.cpp | 1 +
flang/lib/Optimizer/CodeGen/CodeGen.cpp | 3 +
flang/lib/Optimizer/CodeGen/Target.cpp | 73 +++++++++++--------
flang/lib/Optimizer/CodeGen/TargetRewrite.cpp | 7 +-
flang/lib/Optimizer/CodeGen/TypeConverter.cpp | 4 +-
.../Optimizer/Dialect/Support/FIRContext.cpp | 17 +++++
flang/test/Fir/target-rewrite-target-abi.fir | 24 ++++++
10 files changed, 117 insertions(+), 43 deletions(-)
create mode 100644 flang/test/Fir/target-rewrite-target-abi.fir
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
+ }
+}
>From 6bb322c5e3fc8cb7bdbf41884bd902ebc2d5c416 Mon Sep 17 00:00:00 2001
From: Philipp Rados <philipp.rados at openchip.com>
Date: Thu, 11 Jun 2026 12:13:03 +0200
Subject: [PATCH 2/3] Remove target-abi from FIRToLLVMLowering
---
flang/include/flang/Optimizer/CodeGen/CGPasses.td | 2 --
flang/lib/Optimizer/CodeGen/CodeGen.cpp | 3 ---
2 files changed, 5 deletions(-)
diff --git a/flang/include/flang/Optimizer/CodeGen/CGPasses.td b/flang/include/flang/Optimizer/CodeGen/CGPasses.td
index ace3dadc590c8..26cb7ba4b99c1 100644
--- a/flang/include/flang/Optimizer/CodeGen/CGPasses.td
+++ b/flang/include/flang/Optimizer/CodeGen/CGPasses.td
@@ -35,8 +35,6 @@ 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",
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index ec6e31eecdcc1..6b1acba393170 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -4663,9 +4663,6 @@ class FIRToLLVMLowering
if (!forcedTargetFeatures.empty())
fir::setTargetFeatures(mod, forcedTargetFeatures);
- if (!forcedTargetABI.empty())
- fir::setTargetABI(mod, forcedTargetABI);
-
if (typeDescriptorsRenamedForAssembly)
options.typeDescriptorsRenamedForAssembly =
typeDescriptorsRenamedForAssembly;
>From 0b779edfa5bc132561c3de0e92a8839b531b839b Mon Sep 17 00:00:00 2001
From: Philipp Rados <philipp.rados at openchip.com>
Date: Thu, 11 Jun 2026 12:38:59 +0200
Subject: [PATCH 3/3] Retrigger CI
More information about the flang-commits
mailing list