aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
diff options
context:
space:
mode:
authorjeanPerier <jperier@nvidia.com>2025-02-12 17:31:34 +0100
committerGitHub <noreply@github.com>2025-02-12 17:31:34 +0100
commit5836d918450b07886556c519a81776db9ac91eea (patch)
tree6d88a6c8c3c85980e97dbc4706a2219d95b422fb /flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
parenteff3c343b08cfc46016708b3182ac062d45b3e21 (diff)
downloadllvm-5836d918450b07886556c519a81776db9ac91eea.zip
llvm-5836d918450b07886556c519a81776db9ac91eea.tar.gz
llvm-5836d918450b07886556c519a81776db9ac91eea.tar.bz2
[flang] add ABI argument attributes in indirect calls (#126896)
Last piece that implements the TODO for sret and byval setting on indirect calls. This includes a fix to the codegen last patch. I thought types in in type attributes were automatically converted in dialect conversion passes, but that is not the case. The sret and byval type needs to be converted to llvm types in codegen (mlir FuncOp conversion is doing a similar conversion).
Diffstat (limited to 'flang/lib/Optimizer/CodeGen/TargetRewrite.cpp')
-rw-r--r--flang/lib/Optimizer/CodeGen/TargetRewrite.cpp43
1 files changed, 34 insertions, 9 deletions
diff --git a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
index c099a08..5c9da03 100644
--- a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
+++ b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp
@@ -534,19 +534,44 @@ public:
} else if constexpr (std::is_same_v<std::decay_t<A>, fir::CallOp>) {
fir::CallOp newCall;
if (callOp.getCallee()) {
- newCall =
- rewriter->create<A>(loc, *callOp.getCallee(), newResTys, newOpers);
+ newCall = rewriter->create<fir::CallOp>(loc, *callOp.getCallee(),
+ newResTys, newOpers);
} else {
- // TODO: llvm dialect must be updated to propagate argument on
- // attributes for indirect calls. See:
- // https://discourse.llvm.org/t/should-llvm-callop-be-able-to-carry-argument-attributes-for-indirect-calls/75431
- if (hasByValOrSRetArgs(newInTyAndAttrs))
- TODO(loc,
- "passing argument or result on the stack in indirect calls");
newOpers[0].setType(mlir::FunctionType::get(
callOp.getContext(),
mlir::TypeRange{newInTypes}.drop_front(dropFront), newResTys));
- newCall = rewriter->create<A>(loc, newResTys, newOpers);
+ newCall = rewriter->create<fir::CallOp>(loc, newResTys, newOpers);
+ // Set ABI argument attributes on call operation since they are not
+ // accessible via a FuncOp in indirect calls.
+ if (hasByValOrSRetArgs(newInTyAndAttrs)) {
+ llvm::SmallVector<mlir::Attribute> argAttrsArray;
+ for (const auto &arg :
+ llvm::ArrayRef<fir::CodeGenSpecifics::TypeAndAttr>(
+ newInTyAndAttrs)
+ .drop_front(dropFront)) {
+ mlir::NamedAttrList argAttrs;
+ const auto &attr = std::get<fir::CodeGenSpecifics::Attributes>(arg);
+ if (attr.isByVal()) {
+ mlir::Type elemType =
+ fir::dyn_cast_ptrOrBoxEleTy(std::get<mlir::Type>(arg));
+ argAttrs.set(mlir::LLVM::LLVMDialect::getByValAttrName(),
+ mlir::TypeAttr::get(elemType));
+ } else if (attr.isSRet()) {
+ mlir::Type elemType =
+ fir::dyn_cast_ptrOrBoxEleTy(std::get<mlir::Type>(arg));
+ argAttrs.set(mlir::LLVM::LLVMDialect::getStructRetAttrName(),
+ mlir::TypeAttr::get(elemType));
+ if (auto align = attr.getAlignment()) {
+ argAttrs.set(mlir::LLVM::LLVMDialect::getAlignAttrName(),
+ rewriter->getIntegerAttr(
+ rewriter->getIntegerType(32), align));
+ }
+ }
+ argAttrsArray.emplace_back(
+ argAttrs.getDictionary(rewriter->getContext()));
+ }
+ newCall.setArgAttrsAttr(rewriter->getArrayAttr(argAttrsArray));
+ }
}
LLVM_DEBUG(llvm::dbgs() << "replacing call with " << newCall << '\n');
if (wrap)