diff --git a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp --- a/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp +++ b/mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp @@ -56,6 +56,9 @@ #define PASS_NAME "convert-func-to-llvm" +static constexpr StringRef varargsAttrName = "func.varargs"; +static constexpr StringRef linkageAttrName = "llvm.linkage"; + /// Only retain those attributes that are not constructed by /// `LLVMFuncOp::build`. If `filterArgAttrs` is set, also filter out argument /// attributes. @@ -64,7 +67,8 @@ for (const NamedAttribute &attr : func->getAttrs()) { if (attr.getName() == SymbolTable::getSymbolAttrName() || attr.getName() == func.getFunctionTypeAttrName() || - attr.getName() == "func.varargs" || + attr.getName() == linkageAttrName || + attr.getName() == varargsAttrName || (filterArgAndResAttrs && (attr.getName() == func.getArgAttrsAttrName() || attr.getName() == func.getResAttrsAttrName()))) @@ -290,7 +294,7 @@ ConversionPatternRewriter &rewriter) const { // Convert the original function arguments. They are converted using the // LLVMTypeConverter provided to this legalization pattern. - auto varargsAttr = funcOp->getAttrOfType("func.varargs"); + auto varargsAttr = funcOp->getAttrOfType(varargsAttrName); TypeConverter::SignatureConversion result(funcOp.getNumArguments()); auto llvmType = getTypeConverter()->convertFunctionSignature( funcOp.getFunctionType(), varargsAttr && varargsAttr.getValue(), @@ -356,22 +360,16 @@ attributes.push_back(rewriter.getNamedAttr( funcOp.getArgAttrsAttrName(), rewriter.getArrayAttr(newArgAttrs))); } - for (const auto &pair : llvm::enumerate(attributes)) { - if (pair.value().getName() == "llvm.linkage") { - attributes.erase(attributes.begin() + pair.index()); - break; - } - } // Create an LLVM function, use external linkage by default until MLIR // functions have linkage. LLVM::Linkage linkage = LLVM::Linkage::External; - if (funcOp->hasAttr("llvm.linkage")) { + if (funcOp->hasAttr(linkageAttrName)) { auto attr = - funcOp->getAttr("llvm.linkage").dyn_cast(); + funcOp->getAttr(linkageAttrName).dyn_cast(); if (!attr) { - funcOp->emitError() - << "Contains llvm.linkage attribute not of type LLVM::LinkageAttr"; + funcOp->emitError() << "Contains " << linkageAttrName + << " attribute not of type LLVM::LinkageAttr"; return nullptr; } linkage = attr.getLinkage(); diff --git a/mlir/test/Conversion/FuncToLLVM/convert-funcs.mlir b/mlir/test/Conversion/FuncToLLVM/convert-funcs.mlir --- a/mlir/test/Conversion/FuncToLLVM/convert-funcs.mlir +++ b/mlir/test/Conversion/FuncToLLVM/convert-funcs.mlir @@ -40,6 +40,10 @@ // CHECK-LABEL: llvm.func extern_weak @llvmlinkage(i32) func.func private @llvmlinkage(i32) attributes { "llvm.linkage" = #llvm.linkage } +// CHECK-LABEL: llvm.func @llvmreadnone(i32) +// CHECK-SAME: llvm.readnone +func.func private @llvmreadnone(i32) attributes { llvm.readnone } + // CHECK-LABEL: llvm.func @body(i32) func.func private @body(i32) diff --git a/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-callers.mlir b/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-callers.mlir --- a/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-callers.mlir +++ b/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-callers.mlir @@ -68,3 +68,12 @@ %2 = arith.constant 2 : i32 return %0, %1, %2 : f32, memref, i32 } + +// CHECK: llvm.func @drop_linkage_attr() -> (!llvm.struct{{.*}} {test.returnOne}) +// CHECK-LABEL: llvm.func @_mlir_ciface_drop_linkage_attr +// CHECK-NOT: llvm.linkage +// CHECK: %{{.*}}: !llvm.ptr{{.*}} {test.returnOne} +func.func @drop_linkage_attr() -> (memref {test.returnOne}) attributes { llvm.linkage = #llvm.linkage } { + %0 = memref.alloc() : memref + return %0 : memref +} diff --git a/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-functions.mlir b/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-functions.mlir --- a/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-functions.mlir +++ b/mlir/test/Conversion/FuncToLLVM/emit-c-wrappers-for-external-functions.mlir @@ -39,3 +39,9 @@ // CHECK-LABEL: llvm.func @_mlir_ciface_multiple_arg_attr_multiple_res_attr // CHECK: (!llvm.ptr<{{.*}}> {llvm.struct_attrs = [{}, {test.returnOne = 1 : i64}, {test.returnTwo = 2 : i64}]}, !llvm.ptr<{{.*}}> {test.argZero = 0 : i64}, f32, i32 {test.argTwo = 2 : i64} func.func private @multiple_arg_attr_multiple_res_attr(%arg0: memref {test.argZero = 0}, %arg1: f32, %arg2: i32 {test.argTwo = 2}) -> (f32, memref {test.returnOne = 1}, i32 {test.returnTwo = 2}) + +// CHECK: llvm.func weak @drop_linkage_attr() -> (!llvm.struct{{.*}} {test.returnOne}) +// CHECK-LABEL: llvm.func @_mlir_ciface_drop_linkage_attr +// CHECK-NOT: llvm.linkage +// CHECK: !llvm.ptr{{.*}} {test.returnOne} +func.func private @drop_linkage_attr() -> (memref {test.returnOne}) attributes { llvm.linkage = #llvm.linkage }