[Mlir-commits] [mlir] [mlir][func] Account for named attributes without a dialect prefix in `FuncToLLVM` lowering pass (PR #182987)
Ayokunle Amodu
llvmlistbot at llvm.org
Wed Feb 25 07:52:55 PST 2026
https://github.com/ayokunle321 updated https://github.com/llvm/llvm-project/pull/182987
>From 46fa4abe8bd4902988c19e3ecf5564966606a095 Mon Sep 17 00:00:00 2001
From: Ayokunle Amodu <ayokunle321 at gmail.com>
Date: Mon, 23 Feb 2026 19:34:28 -0700
Subject: [PATCH 1/2] fix handling of attribute names
---
mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp | 29 ++++++++++++++-----
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
index 2220f61ed8a07..d0b33bae6d0a5 100644
--- a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
+++ b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
@@ -52,10 +52,15 @@ static constexpr StringRef varargsAttrName = "func.varargs";
static constexpr StringRef linkageAttrName = "llvm.linkage";
static constexpr StringRef barePtrAttrName = "llvm.bareptr";
+static constexpr StringRef varargsAttrNameNoPrefix = "varargs";
+static constexpr StringRef linkageAttrNameNoPrefix = "linkage";
+static constexpr StringRef barePtrAttrNameNoPrefix = "bareptr";
+
/// Return `true` if the `op` should use bare pointer calling convention.
static bool shouldUseBarePtrCallConv(Operation *op,
const LLVMTypeConverter *typeConverter) {
- return (op && op->hasAttr(barePtrAttrName)) ||
+ return (op && (op->hasAttr(barePtrAttrName) ||
+ op->hasAttr(barePtrAttrNameNoPrefix))) ||
typeConverter->getOptions().useBarePtrCallConv;
}
@@ -65,7 +70,9 @@ static void filterFuncAttributes(FunctionOpInterface func,
SmallVectorImpl<NamedAttribute> &result) {
for (const NamedAttribute &attr : func->getDiscardableAttrs()) {
if (attr.getName() == linkageAttrName ||
+ attr.getName() == linkageAttrNameNoPrefix ||
attr.getName() == varargsAttrName ||
+ attr.getName() == varargsAttrNameNoPrefix ||
attr.getName() == LLVM::LLVMDialect::getReadnoneAttrName())
continue;
result.push_back(attr);
@@ -299,7 +306,10 @@ FailureOr<LLVM::LLVMFuncOp> mlir::convertFuncOpToLLVMFuncOp(
// Convert the original function arguments. They are converted using the
// LLVMTypeConverter provided to this legalization pattern.
- auto varargsAttr = funcOp->getAttrOfType<BoolAttr>(varargsAttrName);
+ auto varargsAttr =
+ funcOp->getAttrOfType<BoolAttr>(varargsAttrName)
+ ? funcOp->getAttrOfType<BoolAttr>(varargsAttrName)
+ : funcOp->getAttrOfType<BoolAttr>(varargsAttrNameNoPrefix);
// Gather `llvm.byval` and `llvm.byref` arguments whose type convertion was
// overriden with an LLVM pointer type for later processing.
SmallVector<std::optional<NamedAttribute>> byValRefNonPtrAttrs;
@@ -323,9 +333,12 @@ FailureOr<LLVM::LLVMFuncOp> mlir::convertFuncOpToLLVMFuncOp(
// Create an LLVM function, use external linkage by default until MLIR
// functions have linkage.
LLVM::Linkage linkage = LLVM::Linkage::External;
- if (funcOp->hasAttr(linkageAttrName)) {
- auto attr =
- dyn_cast<mlir::LLVM::LinkageAttr>(funcOp->getAttr(linkageAttrName));
+ if (funcOp->hasAttr(linkageAttrName) ||
+ funcOp->hasAttr(linkageAttrNameNoPrefix)) {
+ auto attr = dyn_cast_or_null<mlir::LLVM::LinkageAttr>(
+ funcOp->getAttr(linkageAttrName)
+ ? funcOp->getAttr(linkageAttrName)
+ : funcOp->getAttr(linkageAttrNameNoPrefix));
if (!attr) {
funcOp->emitError() << "Contains " << linkageAttrName
<< " attribute not of type LLVM::LinkageAttr";
@@ -651,13 +664,15 @@ class CallOpLowering : public CallOpInterfaceLowering<func::CallOp> {
Operation *callee =
symbolTables->lookupNearestSymbolFrom(callOp, callOp.getCalleeAttr());
useBarePtrCallConv =
- callee != nullptr && callee->hasAttr(barePtrAttrName);
+ callee != nullptr && (callee->hasAttr(barePtrAttrName) ||
+ callee->hasAttr(barePtrAttrNameNoPrefix));
} else {
// Warning: This is a linear lookup.
Operation *callee =
SymbolTable::lookupNearestSymbolFrom(callOp, callOp.getCalleeAttr());
useBarePtrCallConv =
- callee != nullptr && callee->hasAttr(barePtrAttrName);
+ callee != nullptr && (callee->hasAttr(barePtrAttrName) ||
+ callee->hasAttr(barePtrAttrNameNoPrefix));
}
return matchAndRewriteImpl(callOp, adaptor, rewriter, useBarePtrCallConv);
}
>From bb1ea24e3ffad6d1423d5c22c488f890e0457edb Mon Sep 17 00:00:00 2001
From: Ayokunle Amodu <ayokunle321 at gmail.com>
Date: Wed, 25 Feb 2026 08:52:25 -0700
Subject: [PATCH 2/2] replace hardcoded attribute names in filter
---
mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp | 36 ++++++-------------
1 file changed, 11 insertions(+), 25 deletions(-)
diff --git a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
index d0b33bae6d0a5..f2377f480a3bc 100644
--- a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
+++ b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp
@@ -52,15 +52,10 @@ static constexpr StringRef varargsAttrName = "func.varargs";
static constexpr StringRef linkageAttrName = "llvm.linkage";
static constexpr StringRef barePtrAttrName = "llvm.bareptr";
-static constexpr StringRef varargsAttrNameNoPrefix = "varargs";
-static constexpr StringRef linkageAttrNameNoPrefix = "linkage";
-static constexpr StringRef barePtrAttrNameNoPrefix = "bareptr";
-
/// Return `true` if the `op` should use bare pointer calling convention.
static bool shouldUseBarePtrCallConv(Operation *op,
const LLVMTypeConverter *typeConverter) {
- return (op && (op->hasAttr(barePtrAttrName) ||
- op->hasAttr(barePtrAttrNameNoPrefix))) ||
+ return (op && op->hasAttr(barePtrAttrName)) ||
typeConverter->getOptions().useBarePtrCallConv;
}
@@ -68,12 +63,11 @@ static bool shouldUseBarePtrCallConv(Operation *op,
/// `LLVMFuncOp::build`.
static void filterFuncAttributes(FunctionOpInterface func,
SmallVectorImpl<NamedAttribute> &result) {
+ llvm::SmallDenseSet<StringRef> odsAttrNames(
+ LLVM::LLVMFuncOp::getAttributeNames().begin(),
+ LLVM::LLVMFuncOp::getAttributeNames().end());
for (const NamedAttribute &attr : func->getDiscardableAttrs()) {
- if (attr.getName() == linkageAttrName ||
- attr.getName() == linkageAttrNameNoPrefix ||
- attr.getName() == varargsAttrName ||
- attr.getName() == varargsAttrNameNoPrefix ||
- attr.getName() == LLVM::LLVMDialect::getReadnoneAttrName())
+ if (odsAttrNames.contains(attr.getName().strref()))
continue;
result.push_back(attr);
}
@@ -306,10 +300,7 @@ FailureOr<LLVM::LLVMFuncOp> mlir::convertFuncOpToLLVMFuncOp(
// Convert the original function arguments. They are converted using the
// LLVMTypeConverter provided to this legalization pattern.
- auto varargsAttr =
- funcOp->getAttrOfType<BoolAttr>(varargsAttrName)
- ? funcOp->getAttrOfType<BoolAttr>(varargsAttrName)
- : funcOp->getAttrOfType<BoolAttr>(varargsAttrNameNoPrefix);
+ auto varargsAttr = funcOp->getAttrOfType<BoolAttr>(varargsAttrName);
// Gather `llvm.byval` and `llvm.byref` arguments whose type convertion was
// overriden with an LLVM pointer type for later processing.
SmallVector<std::optional<NamedAttribute>> byValRefNonPtrAttrs;
@@ -333,12 +324,9 @@ FailureOr<LLVM::LLVMFuncOp> mlir::convertFuncOpToLLVMFuncOp(
// Create an LLVM function, use external linkage by default until MLIR
// functions have linkage.
LLVM::Linkage linkage = LLVM::Linkage::External;
- if (funcOp->hasAttr(linkageAttrName) ||
- funcOp->hasAttr(linkageAttrNameNoPrefix)) {
- auto attr = dyn_cast_or_null<mlir::LLVM::LinkageAttr>(
- funcOp->getAttr(linkageAttrName)
- ? funcOp->getAttr(linkageAttrName)
- : funcOp->getAttr(linkageAttrNameNoPrefix));
+ if (funcOp->hasAttr(linkageAttrName)) {
+ auto attr =
+ dyn_cast<mlir::LLVM::LinkageAttr>(funcOp->getAttr(linkageAttrName));
if (!attr) {
funcOp->emitError() << "Contains " << linkageAttrName
<< " attribute not of type LLVM::LinkageAttr";
@@ -664,15 +652,13 @@ class CallOpLowering : public CallOpInterfaceLowering<func::CallOp> {
Operation *callee =
symbolTables->lookupNearestSymbolFrom(callOp, callOp.getCalleeAttr());
useBarePtrCallConv =
- callee != nullptr && (callee->hasAttr(barePtrAttrName) ||
- callee->hasAttr(barePtrAttrNameNoPrefix));
+ callee != nullptr && callee->hasAttr(barePtrAttrName);
} else {
// Warning: This is a linear lookup.
Operation *callee =
SymbolTable::lookupNearestSymbolFrom(callOp, callOp.getCalleeAttr());
useBarePtrCallConv =
- callee != nullptr && (callee->hasAttr(barePtrAttrName) ||
- callee->hasAttr(barePtrAttrNameNoPrefix));
+ callee != nullptr && callee->hasAttr(barePtrAttrName);
}
return matchAndRewriteImpl(callOp, adaptor, rewriter, useBarePtrCallConv);
}
More information about the Mlir-commits
mailing list