diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -1647,7 +1647,8 @@ DefaultValuedAttr:$visibility_, OptionalAttr:$arm_streaming, OptionalAttr:$arm_locally_streaming, - OptionalAttr:$section + OptionalAttr:$section, + OptionalAttr:$unnamed_addr ); let regions = (region AnyRegion:$body); diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -1785,7 +1785,8 @@ getGlobalTypeAttrName(), getConstantAttrName(), getValueAttrName(), getLinkageAttrName(), getUnnamedAddrAttrName(), getThreadLocal_AttrName(), - getVisibility_AttrName(), getComdatAttrName()}); + getVisibility_AttrName(), getComdatAttrName(), + getUnnamedAddrAttrName()}); // Print the trailing type unless it's a string global. if (llvm::dyn_cast_or_null(getValueOrNull())) @@ -2246,6 +2247,12 @@ parseOptionalLLVMKeyword( parser, result, LLVM::Visibility::Default))); + // Parse optional UnnamedAddr, default to None. + result.addAttribute(getUnnamedAddrAttrName(result.name), + parser.getBuilder().getI64IntegerAttr( + parseOptionalLLVMKeyword( + parser, result, LLVM::UnnamedAddr::None))); + // Default to C Calling Convention if no keyword is provided. result.addAttribute( getCConvAttrName(result.name), @@ -2309,6 +2316,11 @@ StringRef visibility = stringifyVisibility(getVisibility_()); if (!visibility.empty()) p << visibility << ' '; + if (auto unnamedAddr = getUnnamedAddr()) { + StringRef str = stringifyUnnamedAddr(*unnamedAddr); + if (!str.empty()) + p << str << ' '; + } if (getCConv() != LLVM::CConv::C) p << stringifyCConv(getCConv()) << ' '; @@ -2336,7 +2348,7 @@ p, *this, {getFunctionTypeAttrName(), getArgAttrsAttrName(), getResAttrsAttrName(), getLinkageAttrName(), getCConvAttrName(), getVisibility_AttrName(), - getComdatAttrName()}); + getComdatAttrName(), getUnnamedAddrAttrName()}); // Print the body if this is not an external function. Region &body = getBody(); diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -1738,6 +1738,9 @@ if (func->hasGC()) funcOp.setGarbageCollector(StringRef(func->getGC())); + if (func->hasAtLeastLocalUnnamedAddr()) + funcOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(func->getUnnamedAddr())); + if (func->hasSection()) funcOp.setSection(StringRef(func->getSection())); diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -1041,6 +1041,9 @@ if (auto gc = function.getGarbageCollector()) llvmFunc->setGC(gc->str()); + + if (auto unnamedAddr = function.getUnnamedAddr()) + llvmFunc->setUnnamedAddr(convertUnnamedAddrToLLVM(*unnamedAddr)); } return success(); diff --git a/mlir/test/Dialect/LLVMIR/func.mlir b/mlir/test/Dialect/LLVMIR/func.mlir --- a/mlir/test/Dialect/LLVMIR/func.mlir +++ b/mlir/test/Dialect/LLVMIR/func.mlir @@ -205,6 +205,11 @@ llvm.return } + // CHECK-LABEL: local_unnamed_addr @local_unnamed_addr_func + llvm.func local_unnamed_addr @local_unnamed_addr_func() { + llvm.return + } + // CHECK: llvm.comdat @__llvm_comdat llvm.comdat @__llvm_comdat { // CHECK: llvm.comdat_selector @any any diff --git a/mlir/test/Target/LLVMIR/Import/function-attributes.ll b/mlir/test/Target/LLVMIR/Import/function-attributes.ll --- a/mlir/test/Target/LLVMIR/Import/function-attributes.ll +++ b/mlir/test/Target/LLVMIR/Import/function-attributes.ll @@ -217,3 +217,15 @@ define void @section_func() section ".section.name" { ret void } + +// ----- + +; CHECK-LABEL: local_unnamed_addr @local_unnamed_addr_func +define void @local_unnamed_addr_func() local_unnamed_addr { + ret void +} + +// ----- + +; CHECK-LABEL: unnamed_addr @unnamed_addr_func +declare void @unnamed_addr_func() unnamed_addr diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir --- a/mlir/test/Target/LLVMIR/llvmir.mlir +++ b/mlir/test/Target/LLVMIR/llvmir.mlir @@ -1642,6 +1642,20 @@ // ----- +// CHECK-LABEL: @local_unnamed_addr_func +// CHECK-SAME: local_unnamed_addr +llvm.func local_unnamed_addr @local_unnamed_addr_func() { + llvm.return +} + +// ----- + +// CHECK-LABEL: @unnamed_addr_func +// CHECK-SAME: unnamed_addr +llvm.func unnamed_addr @unnamed_addr_func() + +// ----- + // CHECK-LABEL: @callFreezeOp llvm.func @callFreezeOp(%x : i32) { // CHECK: freeze i32 %{{[0-9]+}}