[Mlir-commits] [mlir] [MLIR][LLVM] Implement LLVM dialect support for global aliases (PR #125295)
Bruno Cardoso Lopes
llvmlistbot at llvm.org
Tue Feb 4 18:26:00 PST 2025
https://github.com/bcardosolopes updated https://github.com/llvm/llvm-project/pull/125295
>From cff1cd3876f8250e2f4fc2bcbcd7499a33a82323 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Fri, 24 Jan 2025 14:21:55 -0800
Subject: [PATCH 01/21] [MLIR][LLVM] Implement LLVM dialect support for global
aliases
This includes support for module translation and module import and add tests for both.
ClangIR cannot currently lower global aliases to LLVM because of missing
support for this.
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 86 +++++++++
.../include/mlir/Target/LLVMIR/ModuleImport.h | 8 +
.../mlir/Target/LLVMIR/ModuleTranslation.h | 11 ++
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 172 ++++++++++++++++++
mlir/lib/Target/LLVMIR/ModuleImport.cpp | 60 +++++-
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 68 ++++++-
mlir/test/Target/LLVMIR/Import/alias.ll | 45 +++++
mlir/test/Target/LLVMIR/alias.mlir | 49 +++++
8 files changed, 496 insertions(+), 3 deletions(-)
create mode 100644 mlir/test/Target/LLVMIR/Import/alias.ll
create mode 100644 mlir/test/Target/LLVMIR/alias.mlir
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index b2281536aa40b6..6687d31e326520 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1443,6 +1443,92 @@ def LLVM_GlobalDtorsOp : LLVM_Op<"mlir.global_dtors", [
let hasVerifier = 1;
}
+def LLVM_AliasOp : LLVM_Op<"mlir.alias",
+ [IsolatedFromAbove, SingleBlockImplicitTerminator<"ReturnOp">, Symbol]> {
+ let arguments = (ins
+ TypeAttr:$alias_type,
+ StrAttr:$sym_name,
+ Linkage:$linkage,
+ UnitAttr:$dso_local,
+ UnitAttr:$thread_local_,
+ UnitAttr:$externally_initialized,
+ DefaultValuedAttr<ConfinedAttr<I32Attr, [IntNonNegative]>, "0">:$addr_space,
+ OptionalAttr<UnnamedAddr>:$unnamed_addr,
+ OptionalAttr<StrAttr>:$section,
+ OptionalAttr<SymbolRefAttr>:$comdat,
+ DefaultValuedAttr<Visibility, "mlir::LLVM::Visibility::Default">:$visibility_
+ );
+ let summary = "LLVM dialect alias.";
+ let description = [{
+ `llvm.mlir.alias` is a top level operation that defines a global alias for
+ global variables and functions. The operation is always initialized by
+ using a initializer region which could be a direct map to another global
+ value or contain some address computation on top of it.
+
+ It uses an @-identifier for its value, which will be uniqued by the module
+ with respect to other @-identifiers in it.
+
+ Similarly to functions and globals, they can also have a linkage attribute.
+ This attribute is placed between `llvm.mlir.alias` and the symbol name. If
+ the attribute is omitted, `external` linkage is assumed by default.
+
+ Examples:
+
+ ```mlir
+ // Global alias use @-identifiers.
+ llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
+ %0 = llvm.mlir.addressof @some_function : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+ }
+
+ // More complex initialization.
+ llvm.mlir.alias linkonce_odr hidden @glob
+ {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32> {
+ %0 = llvm.mlir.constant(1234 : i64) : i64
+ %1 = llvm.mlir.addressof @glob.private : !llvm.ptr
+ %2 = llvm.ptrtoint %1 : !llvm.ptr to i64
+ %3 = llvm.add %2, %0 : i64
+ %4 = llvm.inttoptr %3 : i64 to !llvm.ptr
+ llvm.return %4 : !llvm.ptr
+ }
+ ```
+ }];
+ let regions = (region AnyRegion:$initializer);
+
+ let builders = [
+ OpBuilder<(ins "Type":$type, "Linkage":$linkage,
+ "StringRef":$name,
+ CArg<"unsigned", "0">:$addrSpace,
+ CArg<"bool", "false">:$dsoLocal,
+ CArg<"bool", "false">:$thread_local_,
+ CArg<"SymbolRefAttr", "{}">:$comdat,
+ CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs,
+ CArg<"ArrayRef<Attribute>", "{}">:$dbgExprs)>
+ ];
+
+ let extraClassDeclaration = [{
+ /// Return the LLVM type of the global alias.
+ Type getType() {
+ return getAliasType();
+ }
+ /// Return the initializer region. This may be empty, but if it is not it
+ /// terminates in an `llvm.return` op with the initializer value.
+ Region &getInitializerRegion() {
+ return getOperation()->getRegion(0);
+ }
+ /// Return the initializer block. The initializer region always exist
+ /// (differently from llvm.global) and it terminates with an `llvm.return`
+ /// op with the aliasee value.
+ Block *getInitializerBlock() {
+ return &getInitializerRegion().front();
+ }
+ }];
+
+ let hasCustomAssemblyFormat = 1;
+ let hasVerifier = 1;
+ let hasRegionVerifier = 1;
+}
+
def LLVM_ComdatSelectorOp : LLVM_Op<"comdat_selector", [Symbol]> {
let arguments = (ins
SymbolNameAttr:$sym_name,
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
index 80ae4d679624c2..d4032c6bc4356b 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h
@@ -67,6 +67,9 @@ class ModuleImport {
/// Converts all global variables of the LLVM module to MLIR global variables.
LogicalResult convertGlobals();
+ /// Converts all aliases of the LLVM module to MLIR variables.
+ LogicalResult convertAliases();
+
/// Converts the data layout of the LLVM module to an MLIR data layout
/// specification.
LogicalResult convertDataLayout();
@@ -288,6 +291,9 @@ class ModuleImport {
LogicalResult convertGlobal(llvm::GlobalVariable *globalVar);
/// Imports the magic globals "global_ctors" and "global_dtors".
LogicalResult convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar);
+ /// Converts an LLVM global alias variable into an MLIR LLVM dialect alias
+ /// operation if a conversion exists. Otherwise, returns failure.
+ LogicalResult convertAlias(llvm::GlobalAlias *alias);
/// Returns personality of `func` as a FlatSymbolRefAttr.
FlatSymbolRefAttr getPersonalityAsAttr(llvm::Function *func);
/// Imports `bb` into `block`, which must be initially empty.
@@ -406,6 +412,8 @@ class ModuleImport {
Operation *constantInsertionOp = nullptr;
/// Operation to insert the next global after.
Operation *globalInsertionOp = nullptr;
+ /// Operation to insert the next alias after.
+ Operation *aliasInsertionOp = nullptr;
/// Operation to insert comdat selector operations into.
ComdatOp globalComdatOp = nullptr;
/// The current context.
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
index 1b62437761ed9d..28bc3642eb73dc 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
@@ -188,6 +188,12 @@ class ModuleTranslation {
return globalsMapping.lookup(op);
}
+ /// Finds an LLVM IR global value that corresponds to the given MLIR operation
+ /// defining a global alias value.
+ llvm::GlobalValue *lookupAlias(Operation *op) {
+ return aliasesMapping.lookup(op);
+ }
+
/// Returns the OpenMP IR builder associated with the LLVM IR module being
/// constructed.
llvm::OpenMPIRBuilder *getOpenMPBuilder();
@@ -322,6 +328,7 @@ class ModuleTranslation {
LogicalResult convertFunctions();
LogicalResult convertComdats();
LogicalResult convertGlobals();
+ LogicalResult convertAliases();
LogicalResult convertOneFunction(LLVMFuncOp func);
LogicalResult convertBlockImpl(Block &bb, bool ignoreArguments,
llvm::IRBuilderBase &builder,
@@ -366,6 +373,10 @@ class ModuleTranslation {
/// Mappings between llvm.mlir.global definitions and corresponding globals.
DenseMap<Operation *, llvm::GlobalValue *> globalsMapping;
+ /// Mappings between llvm.mlir.alias definitions and corresponding global
+ /// aliases.
+ DenseMap<Operation *, llvm::GlobalValue *> aliasesMapping;
+
/// A stateful object used to translate types.
TypeToLLVMIRTranslator typeTranslator;
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index ef5f1b069b40a3..10ed998a808c86 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -2422,6 +2422,178 @@ LogicalResult GlobalDtorsOp::verify() {
return success();
}
+//===----------------------------------------------------------------------===//
+// Builder, printer and verifier for LLVM::GlobalOp.
+//===----------------------------------------------------------------------===//
+
+void AliasOp::build(OpBuilder &builder, OperationState &result, Type type,
+ Linkage linkage, StringRef name, unsigned addrSpace,
+ bool dsoLocal, bool threadLocal, SymbolRefAttr comdat,
+ ArrayRef<NamedAttribute> attrs,
+ ArrayRef<Attribute> dbgExprs) {
+ result.addAttribute(getSymNameAttrName(result.name),
+ builder.getStringAttr(name));
+ result.addAttribute(getAliasTypeAttrName(result.name), TypeAttr::get(type));
+ if (dsoLocal)
+ result.addAttribute(getDsoLocalAttrName(result.name),
+ builder.getUnitAttr());
+ if (threadLocal)
+ result.addAttribute(getThreadLocal_AttrName(result.name),
+ builder.getUnitAttr());
+ if (comdat)
+ result.addAttribute(getComdatAttrName(result.name), comdat);
+
+ result.addAttribute(getLinkageAttrName(result.name),
+ LinkageAttr::get(builder.getContext(), linkage));
+ if (addrSpace != 0)
+ result.addAttribute(getAddrSpaceAttrName(result.name),
+ builder.getI32IntegerAttr(addrSpace));
+ result.attributes.append(attrs.begin(), attrs.end());
+
+ result.addRegion();
+}
+
+void AliasOp::print(OpAsmPrinter &p) {
+ p << ' ' << stringifyLinkage(getLinkage()) << ' ';
+ StringRef visibility = stringifyVisibility(getVisibility_());
+ if (!visibility.empty())
+ p << visibility << ' ';
+ if (getThreadLocal_())
+ p << "thread_local ";
+ if (auto unnamedAddr = getUnnamedAddr()) {
+ StringRef str = stringifyUnnamedAddr(*unnamedAddr);
+ if (!str.empty())
+ p << str << ' ';
+ }
+ p.printSymbolName(getSymName());
+ if (auto comdat = getComdat())
+ p << " comdat(" << *comdat << ')';
+
+ // Note that the alignment attribute is printed using the
+ // default syntax here, even though it is an inherent attribute
+ // (as defined in https://mlir.llvm.org/docs/LangRef/#attributes)
+ p.printOptionalAttrDict((*this)->getAttrs(),
+ {SymbolTable::getSymbolAttrName(),
+ getAliasTypeAttrName(), getLinkageAttrName(),
+ getUnnamedAddrAttrName(), getThreadLocal_AttrName(),
+ getVisibility_AttrName(), getComdatAttrName(),
+ getUnnamedAddrAttrName()});
+
+ // Print the trailing type
+ p << " : " << getType();
+
+ Region &initializer = getInitializerRegion();
+ if (!initializer.empty()) {
+ p << ' ';
+ p.printRegion(initializer, /*printEntryBlockArgs=*/false);
+ }
+}
+
+// operation ::= `llvm.mlir.alias` linkage? visibility?
+// (`unnamed_addr` | `local_unnamed_addr`)?
+// `thread_local`? `@` identifier
+// `(` attribute? `)` (`comdat(` symbol-ref-id `)`)?
+// attribute-list? (`:` type)? region
+//
+// The type can be omitted for string attributes, in which case it will be
+// inferred from the value of the string as [strlen(value) x i8].
+ParseResult AliasOp::parse(OpAsmParser &parser, OperationState &result) {
+ MLIRContext *ctx = parser.getContext();
+ // Parse optional linkage, default to External.
+ result.addAttribute(getLinkageAttrName(result.name),
+ LLVM::LinkageAttr::get(
+ ctx, parseOptionalLLVMKeyword<Linkage>(
+ parser, result, LLVM::Linkage::External)));
+
+ // Parse optional visibility, default to Default.
+ result.addAttribute(getVisibility_AttrName(result.name),
+ parser.getBuilder().getI64IntegerAttr(
+ parseOptionalLLVMKeyword<LLVM::Visibility, int64_t>(
+ parser, result, LLVM::Visibility::Default)));
+
+ // Parse optional UnnamedAddr, default to None.
+ result.addAttribute(getUnnamedAddrAttrName(result.name),
+ parser.getBuilder().getI64IntegerAttr(
+ parseOptionalLLVMKeyword<UnnamedAddr, int64_t>(
+ parser, result, LLVM::UnnamedAddr::None)));
+
+ if (succeeded(parser.parseOptionalKeyword("thread_local")))
+ result.addAttribute(getThreadLocal_AttrName(result.name),
+ parser.getBuilder().getUnitAttr());
+
+ StringAttr name;
+ if (parser.parseSymbolName(name, getSymNameAttrName(result.name),
+ result.attributes))
+ return failure();
+
+ if (succeeded(parser.parseOptionalKeyword("comdat"))) {
+ SymbolRefAttr comdat;
+ if (parser.parseLParen() || parser.parseAttribute(comdat) ||
+ parser.parseRParen())
+ return failure();
+
+ result.addAttribute(getComdatAttrName(result.name), comdat);
+ }
+
+ SmallVector<Type, 1> types;
+ if (parser.parseOptionalAttrDict(result.attributes) ||
+ parser.parseOptionalColonTypeList(types))
+ return failure();
+
+ if (types.size() > 1)
+ return parser.emitError(parser.getNameLoc(), "expected zero or one type");
+
+ Region &initRegion = *result.addRegion();
+ if (parser.parseRegion(initRegion).failed())
+ return failure();
+
+ result.addAttribute(getAliasTypeAttrName(result.name),
+ TypeAttr::get(types[0]));
+ return success();
+}
+
+LogicalResult AliasOp::verify() {
+ bool validType = isCompatibleOuterType(getType())
+ ? !llvm::isa<LLVMVoidType, LLVMTokenType,
+ LLVMMetadataType, LLVMLabelType>(getType())
+ : llvm::isa<PointerElementTypeInterface>(getType());
+ if (!validType)
+ return emitOpError(
+ "expects type to be a valid element type for an LLVM global");
+ if ((*this)->getParentOp() && !satisfiesLLVMModule((*this)->getParentOp()))
+ return emitOpError("must appear at the module level");
+
+ if (getLinkage() == Linkage::Appending) {
+ if (!llvm::isa<LLVMArrayType>(getType())) {
+ return emitOpError() << "expected array type for '"
+ << stringifyLinkage(Linkage::Appending)
+ << "' linkage";
+ }
+ }
+
+ if (failed(verifyComdat(*this, getComdat())))
+ return failure();
+
+ return success();
+}
+
+LogicalResult AliasOp::verifyRegions() {
+ if (Block *b = getInitializerBlock()) {
+ ReturnOp ret = cast<ReturnOp>(b->getTerminator());
+ if (ret.operand_type_begin() == ret.operand_type_end())
+ return emitOpError("initializer region cannot return void");
+
+ for (Operation &op : *b) {
+ auto iface = dyn_cast<MemoryEffectOpInterface>(op);
+ if (!iface || !iface.hasNoEffect())
+ return op.emitError()
+ << "ops with side effects not allowed in aliases initializers";
+ }
+ }
+
+ return success();
+}
+
//===----------------------------------------------------------------------===//
// ShuffleVectorOp
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 5ebde22cccbdf3..7c8b66b06d1715 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -647,6 +647,16 @@ LogicalResult ModuleImport::convertGlobals() {
return success();
}
+LogicalResult ModuleImport::convertAliases() {
+ for (llvm::GlobalAlias &alias : llvmModule->aliases()) {
+ if (failed(convertAlias(&alias))) {
+ return emitError(UnknownLoc::get(context))
+ << "unhandled global alias: " << diag(alias);
+ }
+ }
+ return success();
+}
+
LogicalResult ModuleImport::convertDataLayout() {
Location loc = mlirModule.getLoc();
DataLayoutImporter dataLayoutImporter(context, llvmModule->getDataLayout());
@@ -952,6 +962,53 @@ ModuleImport::getOrCreateNamelessSymbolName(llvm::GlobalVariable *globalVar) {
return symbolRef;
}
+LogicalResult ModuleImport::convertAlias(llvm::GlobalAlias *alias) {
+ // Insert the global after the last one or at the start of the module.
+ OpBuilder::InsertionGuard guard(builder);
+ if (!aliasInsertionOp)
+ builder.setInsertionPointToStart(mlirModule.getBody());
+ else
+ builder.setInsertionPointAfter(aliasInsertionOp);
+
+ Type type = convertType(alias->getValueType());
+
+ // Workaround to support LLVM's nameless globals. MLIR, in contrast to LLVM,
+ // always requires a symbol name.
+ StringRef aliasName = alias->getName();
+ if (aliasName.empty())
+ return emitError(UnknownLoc::get(builder.getContext()))
+ << "expects valid name";
+
+ AliasOp aliasOp = builder.create<AliasOp>(
+ mlirModule.getLoc(), type, convertLinkageFromLLVM(alias->getLinkage()),
+ StringRef(aliasName),
+ /*addr_space=*/alias->getAddressSpace(),
+ /*dso_local=*/alias->isDSOLocal(),
+ /*thread_local=*/alias->isThreadLocal(), /*comdat=*/SymbolRefAttr(),
+ /*attrs=*/ArrayRef<NamedAttribute>());
+ aliasInsertionOp = aliasOp;
+
+ clearRegionState();
+ Block *block = builder.createBlock(&aliasOp.getInitializerRegion());
+ setConstantInsertionPointToStart(block);
+ FailureOr<Value> initializer = convertConstantExpr(alias->getAliasee());
+ if (failed(initializer))
+ return failure();
+ builder.create<ReturnOp>(aliasOp.getLoc(), *initializer);
+
+ if (alias->hasAtLeastLocalUnnamedAddr()) {
+ aliasOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(alias->getUnnamedAddr()));
+ }
+ if (alias->hasSection())
+ aliasOp.setSection(alias->getSection());
+ aliasOp.setVisibility_(convertVisibilityFromLLVM(alias->getVisibility()));
+
+ if (alias->hasComdat())
+ aliasOp.setComdatAttr(comdatMapping.lookup(alias->getComdat()));
+
+ return success();
+}
+
LogicalResult ModuleImport::convertGlobal(llvm::GlobalVariable *globalVar) {
// Insert the global after the last one or at the start of the module.
OpBuilder::InsertionGuard guard(builder);
@@ -2456,6 +2513,7 @@ mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
return {};
if (failed(moduleImport.convertFunctions()))
return {};
- moduleImport.convertTargetTriple();
+ if (failed(moduleImport.convertAliases()))
+ return {};
return module;
}
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 4367100e3aca68..70b475d83bbe99 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -746,6 +746,8 @@ void ModuleTranslation::forgetMapping(Region ®ion) {
branchMapping.erase(&op);
if (isa<LLVM::GlobalOp>(op))
globalsMapping.erase(&op);
+ if (isa<LLVM::AliasOp>(op))
+ aliasesMapping.erase(&op);
if (isa<LLVM::CallOp>(op))
callMapping.erase(&op);
llvm::append_range(
@@ -1251,6 +1253,66 @@ LogicalResult ModuleTranslation::convertGlobals() {
return success();
}
+/// Convert aliases.
+LogicalResult ModuleTranslation::convertAliases() {
+ for (auto op : getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
+ llvm::Type *type = convertType(op.getType());
+ llvm::Constant *cst = nullptr;
+ auto linkage = convertLinkageToLLVM(op.getLinkage());
+ llvm::Module &llvmMod = *llvmModule;
+
+ llvm::GlobalAlias *var = llvm::GlobalAlias::create(
+ type, op.getAddrSpace(), linkage, op.getSymName(), cst, &llvmMod);
+
+ var->setThreadLocalMode(op.getThreadLocal_()
+ ? llvm::GlobalAlias::GeneralDynamicTLSModel
+ : llvm::GlobalAlias::NotThreadLocal);
+
+ // Note there is no need to steup the comdat because GlobalAlias calls into
+ // the aliasee comdat information automatically.
+
+ if (op.getUnnamedAddr().has_value())
+ var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
+
+ var->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
+
+ aliasesMapping.try_emplace(op, var);
+ }
+
+ // Convert global aliases. This is done after all global aliases
+ // have been created in LLVM IR because a global body may refer to another
+ // global alias. So all aliases need to be mapped first.
+ for (auto op : getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
+ if (Block *initializer = op.getInitializerBlock()) {
+ llvm::IRBuilder<> builder(llvmModule->getContext());
+
+ for (auto &op : initializer->without_terminator()) {
+ if (failed(convertOperation(op, builder)))
+ return emitError(op.getLoc(), "fail to convert alias initializer");
+ auto *cst = dyn_cast<llvm::Constant>(lookupValue(op.getResult(0)));
+ if (!cst)
+ return emitError(op.getLoc(), "unemittable constant value");
+ }
+
+ ReturnOp ret = cast<ReturnOp>(initializer->getTerminator());
+ llvm::Constant *cst =
+ cast<llvm::Constant>(lookupValue(ret.getOperand(0)));
+ assert(aliasesMapping.count(op));
+ auto *alias = cast<llvm::GlobalAlias>(aliasesMapping[op]);
+ alias->setAliasee(cst);
+ }
+ }
+
+ for (auto op : getModuleBody(mlirModule).getOps<LLVM::AliasOp>())
+ if (failed(convertDialectAttributes(op, {})))
+ return failure();
+
+ // Debug info (TODO): finally, update the compile units their respective sets
+ // of global aliases created earlier.
+
+ return success();
+}
+
/// Attempts to add an attribute identified by `key`, optionally with the given
/// `value` to LLVM function `llvmFunc`. Reports errors at `loc` if any. If the
/// attribute has a kind known to LLVM IR, create the attribute of this kind,
@@ -2057,6 +2119,8 @@ mlir::translateModuleToLLVMIR(Operation *module, llvm::LLVMContext &llvmContext,
return nullptr;
if (failed(translator.convertGlobals()))
return nullptr;
+ if (failed(translator.convertAliases()))
+ return nullptr;
if (failed(translator.createTBAAMetadata()))
return nullptr;
if (failed(translator.createIdentMetadata()))
@@ -2066,8 +2130,8 @@ mlir::translateModuleToLLVMIR(Operation *module, llvm::LLVMContext &llvmContext,
// Convert other top-level operations if possible.
for (Operation &o : getModuleBody(module).getOperations()) {
- if (!isa<LLVM::LLVMFuncOp, LLVM::GlobalOp, LLVM::GlobalCtorsOp,
- LLVM::GlobalDtorsOp, LLVM::ComdatOp>(&o) &&
+ if (!isa<LLVM::LLVMFuncOp, LLVM::AliasOp, LLVM::GlobalOp,
+ LLVM::GlobalCtorsOp, LLVM::GlobalDtorsOp, LLVM::ComdatOp>(&o) &&
!o.hasTrait<OpTrait::IsTerminator>() &&
failed(translator.convertOperation(o, llvmBuilder))) {
return nullptr;
diff --git a/mlir/test/Target/LLVMIR/Import/alias.ll b/mlir/test/Target/LLVMIR/Import/alias.ll
new file mode 100644
index 00000000000000..3adbab4f414cfb
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/Import/alias.ll
@@ -0,0 +1,45 @@
+; RUN: mlir-translate --import-llvm %s | FileCheck %s
+
+ at foo_alias = alias ptr, ptr @callee
+
+; CHECK: llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
+; CHECK: %0 = llvm.mlir.addressof @callee : !llvm.ptr
+; CHECK: llvm.return %0 : !llvm.ptr
+; CHECK: }
+
+define internal ptr @callee() {
+entry:
+ ret ptr null
+}
+
+ at zed = global i32 42
+ at foo = alias i32, ptr @zed
+ at foo2 = alias i16, ptr @zed
+
+; CHECK: llvm.mlir.alias external @foo {addr_space = 0 : i32} : i32 {
+; CHECK: %0 = llvm.mlir.addressof @zed : !llvm.ptr
+; CHECK: llvm.return %0 : !llvm.ptr
+; CHECK: }
+; CHECK: llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
+; CHECK: %0 = llvm.mlir.addressof @zed : !llvm.ptr
+; CHECK: llvm.return %0 : !llvm.ptr
+; CHECK: }
+
+ at some_name = constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr undef, ptr null] }
+ at _ZTV1D = alias { [3 x ptr] }, ptr @some_name
+
+; CHECK: llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
+; CHECK: %0 = llvm.mlir.addressof @some_name : !llvm.ptr
+; CHECK: llvm.return %0 : !llvm.ptr
+; CHECK: }
+
+ at glob.private = private constant [32 x i32] zeroinitializer
+ at glob = linkonce_odr hidden alias [32 x i32], inttoptr (i64 add (i64 ptrtoint (ptr @glob.private to i64), i64 1234) to ptr)
+
+; CHECK: llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32> {
+; CHECK: %0 = llvm.mlir.constant(1234 : i64) : i64
+; CHECK: %1 = llvm.mlir.addressof @glob.private : !llvm.ptr
+; CHECK: %2 = llvm.ptrtoint %1 : !llvm.ptr to i64
+; CHECK: %3 = llvm.add %2, %0 : i64
+; CHECK: %4 = llvm.inttoptr %3 : i64 to !llvm.ptr
+; CHECK: llvm.return %4 : !llvm.ptr
\ No newline at end of file
diff --git a/mlir/test/Target/LLVMIR/alias.mlir b/mlir/test/Target/LLVMIR/alias.mlir
new file mode 100644
index 00000000000000..e143aadbd658ae
--- /dev/null
+++ b/mlir/test/Target/LLVMIR/alias.mlir
@@ -0,0 +1,49 @@
+// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+
+llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
+ %0 = llvm.mlir.addressof @callee : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+// CHECK: @foo_alias = alias ptr, ptr @callee
+
+llvm.mlir.alias external @foo {addr_space = 0 : i32} : i32 {
+ %0 = llvm.mlir.addressof @zed : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+// CHECK: @foo = alias i32, ptr @zed
+
+llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
+ %0 = llvm.mlir.addressof @zed : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+// CHECK: @foo2 = alias i16, ptr @zed
+
+llvm.mlir.global external @zed(42 : i32) {addr_space = 0 : i32} : i32
+
+llvm.func internal @callee() -> !llvm.ptr attributes {dso_local} {
+ %0 = llvm.mlir.zero : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
+ %0 = llvm.mlir.addressof @callee : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+// CHECK: @_ZTV1D = alias { [3 x ptr] }, ptr @callee
+
+llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32>
+
+llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32> {
+ %0 = llvm.mlir.constant(1234 : i64) : i64
+ %1 = llvm.mlir.addressof @glob.private : !llvm.ptr
+ %2 = llvm.ptrtoint %1 : !llvm.ptr to i64
+ %3 = llvm.add %2, %0 : i64
+ %4 = llvm.inttoptr %3 : i64 to !llvm.ptr
+ llvm.return %4 : !llvm.ptr
+}
+
+// CHECK: @glob = linkonce_odr hidden alias [32 x i32], inttoptr (i64 add (i64 ptrtoint (ptr @glob.private to i64), i64 1234) to ptr)
\ No newline at end of file
>From 8ccafc93a6a28883eb8a25f2abd83a8fca9f1199 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Fri, 31 Jan 2025 13:28:46 -0800
Subject: [PATCH 02/21] Fix comments
---
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 70b475d83bbe99..6b23e633f8ebe5 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1268,7 +1268,7 @@ LogicalResult ModuleTranslation::convertAliases() {
? llvm::GlobalAlias::GeneralDynamicTLSModel
: llvm::GlobalAlias::NotThreadLocal);
- // Note there is no need to steup the comdat because GlobalAlias calls into
+ // Note there is no need to setup the comdat because GlobalAlias calls into
// the aliasee comdat information automatically.
if (op.getUnnamedAddr().has_value())
@@ -1307,9 +1307,6 @@ LogicalResult ModuleTranslation::convertAliases() {
if (failed(convertDialectAttributes(op, {})))
return failure();
- // Debug info (TODO): finally, update the compile units their respective sets
- // of global aliases created earlier.
-
return success();
}
>From e36ff90df052c628ee465ca2e8ec1422aa778e10 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Fri, 31 Jan 2025 13:30:06 -0800
Subject: [PATCH 03/21] Remove undef from testcase
---
mlir/test/Target/LLVMIR/Import/alias.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/test/Target/LLVMIR/Import/alias.ll b/mlir/test/Target/LLVMIR/Import/alias.ll
index 3adbab4f414cfb..4e1ee01f142acb 100644
--- a/mlir/test/Target/LLVMIR/Import/alias.ll
+++ b/mlir/test/Target/LLVMIR/Import/alias.ll
@@ -25,7 +25,7 @@ entry:
; CHECK: llvm.return %0 : !llvm.ptr
; CHECK: }
- at some_name = constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr undef, ptr null] }
+ at some_name = constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr null] }
@_ZTV1D = alias { [3 x ptr] }, ptr @some_name
; CHECK: llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
>From f12825e506cc0ba0c5b6801f7e8c649f396836ac Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Mon, 3 Feb 2025 11:41:47 -0800
Subject: [PATCH 04/21] Address Tobias review
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 10 ++--
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 52 +++++++--------------
mlir/lib/Target/LLVMIR/ModuleImport.cpp | 16 ++-----
3 files changed, 23 insertions(+), 55 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 6687d31e326520..84b4829addac60 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1451,11 +1451,9 @@ def LLVM_AliasOp : LLVM_Op<"mlir.alias",
Linkage:$linkage,
UnitAttr:$dso_local,
UnitAttr:$thread_local_,
- UnitAttr:$externally_initialized,
DefaultValuedAttr<ConfinedAttr<I32Attr, [IntNonNegative]>, "0">:$addr_space,
OptionalAttr<UnnamedAddr>:$unnamed_addr,
OptionalAttr<StrAttr>:$section,
- OptionalAttr<SymbolRefAttr>:$comdat,
DefaultValuedAttr<Visibility, "mlir::LLVM::Visibility::Default">:$visibility_
);
let summary = "LLVM dialect alias.";
@@ -1465,8 +1463,8 @@ def LLVM_AliasOp : LLVM_Op<"mlir.alias",
using a initializer region which could be a direct map to another global
value or contain some address computation on top of it.
- It uses an @-identifier for its value, which will be uniqued by the module
- with respect to other @-identifiers in it.
+ It uses a symbol for its value, which will be uniqued by the module
+ with respect to other symbols in it.
Similarly to functions and globals, they can also have a linkage attribute.
This attribute is placed between `llvm.mlir.alias` and the symbol name. If
@@ -1501,9 +1499,7 @@ def LLVM_AliasOp : LLVM_Op<"mlir.alias",
CArg<"unsigned", "0">:$addrSpace,
CArg<"bool", "false">:$dsoLocal,
CArg<"bool", "false">:$thread_local_,
- CArg<"SymbolRefAttr", "{}">:$comdat,
- CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs,
- CArg<"ArrayRef<Attribute>", "{}">:$dbgExprs)>
+ CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs)>
];
let extraClassDeclaration = [{
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 10ed998a808c86..316736f053418e 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -2423,14 +2423,13 @@ LogicalResult GlobalDtorsOp::verify() {
}
//===----------------------------------------------------------------------===//
-// Builder, printer and verifier for LLVM::GlobalOp.
+// Builder, printer and verifier for LLVM::AliasOp.
//===----------------------------------------------------------------------===//
void AliasOp::build(OpBuilder &builder, OperationState &result, Type type,
Linkage linkage, StringRef name, unsigned addrSpace,
- bool dsoLocal, bool threadLocal, SymbolRefAttr comdat,
- ArrayRef<NamedAttribute> attrs,
- ArrayRef<Attribute> dbgExprs) {
+ bool dsoLocal, bool threadLocal,
+ ArrayRef<NamedAttribute> attrs) {
result.addAttribute(getSymNameAttrName(result.name),
builder.getStringAttr(name));
result.addAttribute(getAliasTypeAttrName(result.name), TypeAttr::get(type));
@@ -2440,8 +2439,6 @@ void AliasOp::build(OpBuilder &builder, OperationState &result, Type type,
if (threadLocal)
result.addAttribute(getThreadLocal_AttrName(result.name),
builder.getUnitAttr());
- if (comdat)
- result.addAttribute(getComdatAttrName(result.name), comdat);
result.addAttribute(getLinkageAttrName(result.name),
LinkageAttr::get(builder.getContext(), linkage));
@@ -2466,8 +2463,6 @@ void AliasOp::print(OpAsmPrinter &p) {
p << str << ' ';
}
p.printSymbolName(getSymName());
- if (auto comdat = getComdat())
- p << " comdat(" << *comdat << ')';
// Note that the alignment attribute is printed using the
// default syntax here, even though it is an inherent attribute
@@ -2476,8 +2471,7 @@ void AliasOp::print(OpAsmPrinter &p) {
{SymbolTable::getSymbolAttrName(),
getAliasTypeAttrName(), getLinkageAttrName(),
getUnnamedAddrAttrName(), getThreadLocal_AttrName(),
- getVisibility_AttrName(), getComdatAttrName(),
- getUnnamedAddrAttrName()});
+ getVisibility_AttrName(), getUnnamedAddrAttrName()});
// Print the trailing type
p << " : " << getType();
@@ -2492,8 +2486,8 @@ void AliasOp::print(OpAsmPrinter &p) {
// operation ::= `llvm.mlir.alias` linkage? visibility?
// (`unnamed_addr` | `local_unnamed_addr`)?
// `thread_local`? `@` identifier
-// `(` attribute? `)` (`comdat(` symbol-ref-id `)`)?
-// attribute-list? (`:` type)? region
+// `(` attribute? `)`
+// attribute-list? `:` type region
//
// The type can be omitted for string attributes, in which case it will be
// inferred from the value of the string as [strlen(value) x i8].
@@ -2526,15 +2520,6 @@ ParseResult AliasOp::parse(OpAsmParser &parser, OperationState &result) {
result.attributes))
return failure();
- if (succeeded(parser.parseOptionalKeyword("comdat"))) {
- SymbolRefAttr comdat;
- if (parser.parseLParen() || parser.parseAttribute(comdat) ||
- parser.parseRParen())
- return failure();
-
- result.addAttribute(getComdatAttrName(result.name), comdat);
- }
-
SmallVector<Type, 1> types;
if (parser.parseOptionalAttrDict(result.attributes) ||
parser.parseOptionalColonTypeList(types))
@@ -2571,24 +2556,21 @@ LogicalResult AliasOp::verify() {
}
}
- if (failed(verifyComdat(*this, getComdat())))
- return failure();
-
return success();
}
LogicalResult AliasOp::verifyRegions() {
- if (Block *b = getInitializerBlock()) {
- ReturnOp ret = cast<ReturnOp>(b->getTerminator());
- if (ret.operand_type_begin() == ret.operand_type_end())
- return emitOpError("initializer region cannot return void");
-
- for (Operation &op : *b) {
- auto iface = dyn_cast<MemoryEffectOpInterface>(op);
- if (!iface || !iface.hasNoEffect())
- return op.emitError()
- << "ops with side effects not allowed in aliases initializers";
- }
+ Block *b = getInitializerBlock();
+ ReturnOp ret = cast<ReturnOp>(b->getTerminator());
+ if (ret.getNumOperands() == 0 ||
+ !isa<LLVM::LLVMPointerType>(ret.getOperand(0).getType()))
+ return emitOpError("initializer region must always return a pointer");
+
+ for (Operation &op : *b) {
+ auto iface = dyn_cast<MemoryEffectOpInterface>(op);
+ if (!iface || !iface.hasNoEffect())
+ return op.emitError()
+ << "ops with side effects not allowed in aliases initializers";
}
return success();
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 7c8b66b06d1715..0c6bace4e762da 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -971,20 +971,12 @@ LogicalResult ModuleImport::convertAlias(llvm::GlobalAlias *alias) {
builder.setInsertionPointAfter(aliasInsertionOp);
Type type = convertType(alias->getValueType());
-
- // Workaround to support LLVM's nameless globals. MLIR, in contrast to LLVM,
- // always requires a symbol name.
- StringRef aliasName = alias->getName();
- if (aliasName.empty())
- return emitError(UnknownLoc::get(builder.getContext()))
- << "expects valid name";
-
AliasOp aliasOp = builder.create<AliasOp>(
mlirModule.getLoc(), type, convertLinkageFromLLVM(alias->getLinkage()),
- StringRef(aliasName),
+ alias->getName(),
/*addr_space=*/alias->getAddressSpace(),
/*dso_local=*/alias->isDSOLocal(),
- /*thread_local=*/alias->isThreadLocal(), /*comdat=*/SymbolRefAttr(),
+ /*thread_local=*/alias->isThreadLocal(),
/*attrs=*/ArrayRef<NamedAttribute>());
aliasInsertionOp = aliasOp;
@@ -1003,9 +995,6 @@ LogicalResult ModuleImport::convertAlias(llvm::GlobalAlias *alias) {
aliasOp.setSection(alias->getSection());
aliasOp.setVisibility_(convertVisibilityFromLLVM(alias->getVisibility()));
- if (alias->hasComdat())
- aliasOp.setComdatAttr(comdatMapping.lookup(alias->getComdat()));
-
return success();
}
@@ -2515,5 +2504,6 @@ mlir::translateLLVMIRToModule(std::unique_ptr<llvm::Module> llvmModule,
return {};
if (failed(moduleImport.convertAliases()))
return {};
+ moduleImport.convertTargetTriple();
return module;
}
>From 1186559f33cce1d487e97c20c436923cb0d672e5 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Mon, 3 Feb 2025 14:21:49 -0800
Subject: [PATCH 05/21] Add addrspace related tests
---
mlir/test/Target/LLVMIR/Import/alias.ll | 8 ++++++++
mlir/test/Target/LLVMIR/alias.mlir | 11 ++++++++++-
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/mlir/test/Target/LLVMIR/Import/alias.ll b/mlir/test/Target/LLVMIR/Import/alias.ll
index 4e1ee01f142acb..053573812b868c 100644
--- a/mlir/test/Target/LLVMIR/Import/alias.ll
+++ b/mlir/test/Target/LLVMIR/Import/alias.ll
@@ -25,6 +25,14 @@ entry:
; CHECK: llvm.return %0 : !llvm.ptr
; CHECK: }
+ at v1 = global i32 0
+ at a3 = alias i32, addrspacecast (ptr @v1 to ptr addrspace(2))
+; CHECK: llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
+; CHECK: %0 = llvm.mlir.addressof @v1 : !llvm.ptr
+; CHECK: %1 = llvm.addrspacecast %0 : !llvm.ptr to !llvm.ptr<2>
+; CHECK: llvm.return %1 : !llvm.ptr<2>
+; CHECK: }
+
@some_name = constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr null] }
@_ZTV1D = alias { [3 x ptr] }, ptr @some_name
diff --git a/mlir/test/Target/LLVMIR/alias.mlir b/mlir/test/Target/LLVMIR/alias.mlir
index e143aadbd658ae..c47dfa8f38f263 100644
--- a/mlir/test/Target/LLVMIR/alias.mlir
+++ b/mlir/test/Target/LLVMIR/alias.mlir
@@ -46,4 +46,13 @@ llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !l
llvm.return %4 : !llvm.ptr
}
-// CHECK: @glob = linkonce_odr hidden alias [32 x i32], inttoptr (i64 add (i64 ptrtoint (ptr @glob.private to i64), i64 1234) to ptr)
\ No newline at end of file
+// CHECK: @glob = linkonce_odr hidden alias [32 x i32], inttoptr (i64 add (i64 ptrtoint (ptr @glob.private to i64), i64 1234) to ptr)
+
+llvm.mlir.global external @v1(0 : i32) {addr_space = 0 : i32} : i32
+llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
+ %0 = llvm.mlir.addressof @v1 : !llvm.ptr
+ %1 = llvm.addrspacecast %0 : !llvm.ptr to !llvm.ptr<2>
+ llvm.return %1 : !llvm.ptr<2>
+}
+
+// CHECK: @a3 = alias i32, addrspacecast (ptr @v1 to ptr addrspace(2))
\ No newline at end of file
>From 1927cb56a1e0c3e8bc1a73462037dc6c24978abc Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Mon, 3 Feb 2025 14:28:58 -0800
Subject: [PATCH 06/21] Reorganize tests a bit, use -split-input-file
---
mlir/test/Target/LLVMIR/alias.mlir | 36 +++++++++++++++++-------------
1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/mlir/test/Target/LLVMIR/alias.mlir b/mlir/test/Target/LLVMIR/alias.mlir
index c47dfa8f38f263..3471937fbf7217 100644
--- a/mlir/test/Target/LLVMIR/alias.mlir
+++ b/mlir/test/Target/LLVMIR/alias.mlir
@@ -1,39 +1,41 @@
-// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
+// RUN: mlir-translate -mlir-to-llvmir %s -split-input-file | FileCheck %s
+
+llvm.func internal @callee() -> !llvm.ptr attributes {dso_local} {
+ %0 = llvm.mlir.zero : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
%0 = llvm.mlir.addressof @callee : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
+llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
+ %0 = llvm.mlir.addressof @callee : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
// CHECK: @foo_alias = alias ptr, ptr @callee
+// CHECK: @_ZTV1D = alias { [3 x ptr] }, ptr @callee
+
+// -----
+
+llvm.mlir.global external @zed(42 : i32) {addr_space = 0 : i32} : i32
llvm.mlir.alias external @foo {addr_space = 0 : i32} : i32 {
%0 = llvm.mlir.addressof @zed : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
-// CHECK: @foo = alias i32, ptr @zed
-
llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
%0 = llvm.mlir.addressof @zed : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
+// CHECK: @foo = alias i32, ptr @zed
// CHECK: @foo2 = alias i16, ptr @zed
-llvm.mlir.global external @zed(42 : i32) {addr_space = 0 : i32} : i32
-
-llvm.func internal @callee() -> !llvm.ptr attributes {dso_local} {
- %0 = llvm.mlir.zero : !llvm.ptr
- llvm.return %0 : !llvm.ptr
-}
-
-llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
- %0 = llvm.mlir.addressof @callee : !llvm.ptr
- llvm.return %0 : !llvm.ptr
-}
-
-// CHECK: @_ZTV1D = alias { [3 x ptr] }, ptr @callee
+// -----
llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32>
@@ -48,6 +50,8 @@ llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !l
// CHECK: @glob = linkonce_odr hidden alias [32 x i32], inttoptr (i64 add (i64 ptrtoint (ptr @glob.private to i64), i64 1234) to ptr)
+// -----
+
llvm.mlir.global external @v1(0 : i32) {addr_space = 0 : i32} : i32
llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
%0 = llvm.mlir.addressof @v1 : !llvm.ptr
>From 7b27f3a61919c4c239893b78c94f1507acf0a11a Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Mon, 3 Feb 2025 15:05:12 -0800
Subject: [PATCH 07/21] More verification love
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 10 +++--
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 2 +-
mlir/test/Dialect/LLVMIR/invalid.mlir | 44 ++++++++++++++++++++
mlir/test/Target/LLVMIR/Import/alias.ll | 2 +-
mlir/test/Target/LLVMIR/alias.mlir | 2 +-
5 files changed, 53 insertions(+), 7 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 316736f053418e..ff421a044e159f 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -2544,9 +2544,7 @@ LogicalResult AliasOp::verify() {
: llvm::isa<PointerElementTypeInterface>(getType());
if (!validType)
return emitOpError(
- "expects type to be a valid element type for an LLVM global");
- if ((*this)->getParentOp() && !satisfiesLLVMModule((*this)->getParentOp()))
- return emitOpError("must appear at the module level");
+ "expects type to be a valid element type for an LLVM global alias");
if (getLinkage() == Linkage::Appending) {
if (!llvm::isa<LLVMArrayType>(getType())) {
@@ -2566,11 +2564,15 @@ LogicalResult AliasOp::verifyRegions() {
!isa<LLVM::LLVMPointerType>(ret.getOperand(0).getType()))
return emitOpError("initializer region must always return a pointer");
+ auto ptrTy = cast<LLVM::LLVMPointerType>(ret.getOperand(0).getType());
+ if (ptrTy.getAddressSpace() != getAddrSpace())
+ return emitOpError("address space must match initializer returned one");
+
for (Operation &op : *b) {
auto iface = dyn_cast<MemoryEffectOpInterface>(op);
if (!iface || !iface.hasNoEffect())
return op.emitError()
- << "ops with side effects not allowed in aliases initializers";
+ << "ops with side effects are not allowed in alias initializers";
}
return success();
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 6b23e633f8ebe5..8fe9eeed02943c 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1286,7 +1286,7 @@ LogicalResult ModuleTranslation::convertAliases() {
if (Block *initializer = op.getInitializerBlock()) {
llvm::IRBuilder<> builder(llvmModule->getContext());
- for (auto &op : initializer->without_terminator()) {
+ for (mlir::Operation &op : initializer->without_terminator()) {
if (failed(convertOperation(op, builder)))
return emitError(op.getLoc(), "fail to convert alias initializer");
auto *cst = dyn_cast<llvm::Constant>(lookupValue(op.getResult(0)));
diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir
index 5c939318fe3ed6..0d5a418c0be7ae 100644
--- a/mlir/test/Dialect/LLVMIR/invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid.mlir
@@ -1703,3 +1703,47 @@ llvm.func @wrong_number_of_bundle_tags() {
} : (i32, i32) -> ()
llvm.return
}
+
+// -----
+
+llvm.mlir.global external @x(42 : i32) {addr_space = 0 : i32} : i32
+
+// expected-error at +1 {{expects type to be a valid element type for an LLVM global alias}}
+llvm.mlir.alias external @y {addr_space = 0 : i32} : !llvm.label {
+ %0 = llvm.mlir.addressof @x : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+// -----
+
+// expected-error at +1 {{expected array type for 'appending' linkage}}
+llvm.mlir.alias appending @y2 {addr_space = 0 : i32} : i32 {
+ %0 = llvm.mlir.addressof @x : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+// -----
+
+// expected-error at +1 {{initializer region must always return a pointer}}
+llvm.mlir.alias external @y3 {addr_space = 0 : i32} : i32 {
+ %c = llvm.mlir.constant(42 : i64) : i64
+ llvm.return %c : i64
+}
+
+// -----
+
+llvm.mlir.alias external @y4 {addr_space = 0 : i32} : i32 {
+ %0 = llvm.mlir.addressof @x : !llvm.ptr
+ // expected-error at +1 {{ops with side effects are not allowed in alias initializers}}
+ %2 = llvm.load %0 : !llvm.ptr -> i32
+ llvm.return %0 : !llvm.ptr
+}
+
+// -----
+
+// expected-error at +1 {{op address space must match initializer returned one}}
+llvm.mlir.alias external @badspace {addr_space = 3 : i32} : i32 {
+ %0 = llvm.mlir.addressof @x : !llvm.ptr
+ %1 = llvm.addrspacecast %0 : !llvm.ptr to !llvm.ptr<2>
+ llvm.return %1 : !llvm.ptr<2>
+}
diff --git a/mlir/test/Target/LLVMIR/Import/alias.ll b/mlir/test/Target/LLVMIR/Import/alias.ll
index 053573812b868c..c04413c19c1c39 100644
--- a/mlir/test/Target/LLVMIR/Import/alias.ll
+++ b/mlir/test/Target/LLVMIR/Import/alias.ll
@@ -50,4 +50,4 @@ entry:
; CHECK: %2 = llvm.ptrtoint %1 : !llvm.ptr to i64
; CHECK: %3 = llvm.add %2, %0 : i64
; CHECK: %4 = llvm.inttoptr %3 : i64 to !llvm.ptr
-; CHECK: llvm.return %4 : !llvm.ptr
\ No newline at end of file
+; CHECK: llvm.return %4 : !llvm.ptr
diff --git a/mlir/test/Target/LLVMIR/alias.mlir b/mlir/test/Target/LLVMIR/alias.mlir
index 3471937fbf7217..fccbb5422060ad 100644
--- a/mlir/test/Target/LLVMIR/alias.mlir
+++ b/mlir/test/Target/LLVMIR/alias.mlir
@@ -59,4 +59,4 @@ llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
llvm.return %1 : !llvm.ptr<2>
}
-// CHECK: @a3 = alias i32, addrspacecast (ptr @v1 to ptr addrspace(2))
\ No newline at end of file
+// CHECK: @a3 = alias i32, addrspacecast (ptr @v1 to ptr addrspace(2))
>From 82ca97a22fd30c86226b48df4deb3463046ab230 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Mon, 3 Feb 2025 15:53:53 -0800
Subject: [PATCH 08/21] Refactor common parsing bits for GlobalOp and AliasOp
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 61 +++++++++-------------
1 file changed, 26 insertions(+), 35 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index ff421a044e159f..1a8685a8a3e584 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -2188,38 +2188,48 @@ static LogicalResult verifyComdat(Operation *op,
return success();
}
-// operation ::= `llvm.mlir.global` linkage? visibility?
-// (`unnamed_addr` | `local_unnamed_addr`)?
-// `thread_local`? `constant`? `@` identifier
-// `(` attribute? `)` (`comdat(` symbol-ref-id `)`)?
-// attribute-list? (`:` type)? region?
-//
-// The type can be omitted for string attributes, in which case it will be
-// inferred from the value of the string as [strlen(value) x i8].
-ParseResult GlobalOp::parse(OpAsmParser &parser, OperationState &result) {
+template <typename OpType>
+static ParseResult parseCommonGlobalAndAlias(OpAsmParser &parser,
+ OperationState &result) {
MLIRContext *ctx = parser.getContext();
// Parse optional linkage, default to External.
- result.addAttribute(getLinkageAttrName(result.name),
+ result.addAttribute(OpType::getLinkageAttrName(result.name),
LLVM::LinkageAttr::get(
ctx, parseOptionalLLVMKeyword<Linkage>(
parser, result, LLVM::Linkage::External)));
// Parse optional visibility, default to Default.
- result.addAttribute(getVisibility_AttrName(result.name),
+ result.addAttribute(OpType::getVisibility_AttrName(result.name),
parser.getBuilder().getI64IntegerAttr(
parseOptionalLLVMKeyword<LLVM::Visibility, int64_t>(
parser, result, LLVM::Visibility::Default)));
// Parse optional UnnamedAddr, default to None.
- result.addAttribute(getUnnamedAddrAttrName(result.name),
+ result.addAttribute(OpType::getUnnamedAddrAttrName(result.name),
parser.getBuilder().getI64IntegerAttr(
parseOptionalLLVMKeyword<UnnamedAddr, int64_t>(
parser, result, LLVM::UnnamedAddr::None)));
if (succeeded(parser.parseOptionalKeyword("thread_local")))
- result.addAttribute(getThreadLocal_AttrName(result.name),
+ result.addAttribute(OpType::getThreadLocal_AttrName(result.name),
parser.getBuilder().getUnitAttr());
+ return success();
+}
+
+// operation ::= `llvm.mlir.global` linkage? visibility?
+// (`unnamed_addr` | `local_unnamed_addr`)?
+// `thread_local`? `constant`? `@` identifier
+// `(` attribute? `)` (`comdat(` symbol-ref-id `)`)?
+// attribute-list? (`:` type)? region?
+//
+// The type can be omitted for string attributes, in which case it will be
+// inferred from the value of the string as [strlen(value) x i8].
+ParseResult GlobalOp::parse(OpAsmParser &parser, OperationState &result) {
+ // Call into common parsing between GlobalOp and AliasOp.
+ if (parseCommonGlobalAndAlias<GlobalOp>(parser, result).failed())
+ return failure();
+
if (succeeded(parser.parseOptionalKeyword("constant")))
result.addAttribute(getConstantAttrName(result.name),
parser.getBuilder().getUnitAttr());
@@ -2492,28 +2502,9 @@ void AliasOp::print(OpAsmPrinter &p) {
// The type can be omitted for string attributes, in which case it will be
// inferred from the value of the string as [strlen(value) x i8].
ParseResult AliasOp::parse(OpAsmParser &parser, OperationState &result) {
- MLIRContext *ctx = parser.getContext();
- // Parse optional linkage, default to External.
- result.addAttribute(getLinkageAttrName(result.name),
- LLVM::LinkageAttr::get(
- ctx, parseOptionalLLVMKeyword<Linkage>(
- parser, result, LLVM::Linkage::External)));
-
- // Parse optional visibility, default to Default.
- result.addAttribute(getVisibility_AttrName(result.name),
- parser.getBuilder().getI64IntegerAttr(
- parseOptionalLLVMKeyword<LLVM::Visibility, int64_t>(
- parser, result, LLVM::Visibility::Default)));
-
- // Parse optional UnnamedAddr, default to None.
- result.addAttribute(getUnnamedAddrAttrName(result.name),
- parser.getBuilder().getI64IntegerAttr(
- parseOptionalLLVMKeyword<UnnamedAddr, int64_t>(
- parser, result, LLVM::UnnamedAddr::None)));
-
- if (succeeded(parser.parseOptionalKeyword("thread_local")))
- result.addAttribute(getThreadLocal_AttrName(result.name),
- parser.getBuilder().getUnitAttr());
+ // Call into common parsing between GlobalOp and AliasOp.
+ if (parseCommonGlobalAndAlias<AliasOp>(parser, result).failed())
+ return failure();
StringAttr name;
if (parser.parseSymbolName(name, getSymNameAttrName(result.name),
>From 8711298c56defcc491f311b2f701e57905d9ec86 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Mon, 3 Feb 2025 15:58:43 -0800
Subject: [PATCH 09/21] Add roundtrip tests for the parsing/printing
---
mlir/test/Target/LLVMIR/alias.mlir | 41 ++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/mlir/test/Target/LLVMIR/alias.mlir b/mlir/test/Target/LLVMIR/alias.mlir
index fccbb5422060ad..6cd33270ee7d77 100644
--- a/mlir/test/Target/LLVMIR/alias.mlir
+++ b/mlir/test/Target/LLVMIR/alias.mlir
@@ -1,4 +1,5 @@
// RUN: mlir-translate -mlir-to-llvmir %s -split-input-file | FileCheck %s
+// RUN: mlir-opt %s -split-input-file | FileCheck -check-prefix=ROUNDTRIP %s
llvm.func internal @callee() -> !llvm.ptr attributes {dso_local} {
%0 = llvm.mlir.zero : !llvm.ptr
@@ -18,6 +19,19 @@ llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3
// CHECK: @foo_alias = alias ptr, ptr @callee
// CHECK: @_ZTV1D = alias { [3 x ptr] }, ptr @callee
+// ROUNDTRIP: llvm.func internal @callee() -> !llvm.ptr attributes {dso_local} {
+// ROUNDTRIP: %0 = llvm.mlir.zero : !llvm.ptr
+// ROUNDTRIP: llvm.return %0 : !llvm.ptr
+// ROUNDTRIP: }
+// ROUNDTRIP: llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
+// ROUNDTRIP: %0 = llvm.mlir.addressof @callee : !llvm.ptr
+// ROUNDTRIP: llvm.return %0 : !llvm.ptr
+// ROUNDTRIP: }
+// ROUNDTRIP: llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
+// ROUNDTRIP: %0 = llvm.mlir.addressof @callee : !llvm.ptr
+// ROUNDTRIP: llvm.return %0 : !llvm.ptr
+// ROUNDTRIP: }
+
// -----
llvm.mlir.global external @zed(42 : i32) {addr_space = 0 : i32} : i32
@@ -35,6 +49,16 @@ llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
// CHECK: @foo = alias i32, ptr @zed
// CHECK: @foo2 = alias i16, ptr @zed
+// ROUNDTRIP: llvm.mlir.global external @zed(42 : i32) {addr_space = 0 : i32} : i32
+// ROUNDTRIP: llvm.mlir.alias external @foo {addr_space = 0 : i32} : i32 {
+// ROUNDTRIP: %0 = llvm.mlir.addressof @zed : !llvm.ptr
+// ROUNDTRIP: llvm.return %0 : !llvm.ptr
+// ROUNDTRIP: }
+// ROUNDTRIP: llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
+// ROUNDTRIP: %0 = llvm.mlir.addressof @zed : !llvm.ptr
+// ROUNDTRIP: llvm.return %0 : !llvm.ptr
+// ROUNDTRIP: }
+
// -----
llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32>
@@ -50,6 +74,16 @@ llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !l
// CHECK: @glob = linkonce_odr hidden alias [32 x i32], inttoptr (i64 add (i64 ptrtoint (ptr @glob.private to i64), i64 1234) to ptr)
+// ROUNDTRIP: llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32>
+// ROUNDTRIP: llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32> {
+// ROUNDTRIP: %0 = llvm.mlir.constant(1234 : i64) : i64
+// ROUNDTRIP: %1 = llvm.mlir.addressof @glob.private : !llvm.ptr
+// ROUNDTRIP: %2 = llvm.ptrtoint %1 : !llvm.ptr to i64
+// ROUNDTRIP: %3 = llvm.add %2, %0 : i64
+// ROUNDTRIP: %4 = llvm.inttoptr %3 : i64 to !llvm.ptr
+// ROUNDTRIP: llvm.return %4 : !llvm.ptr
+// ROUNDTRIP: }
+
// -----
llvm.mlir.global external @v1(0 : i32) {addr_space = 0 : i32} : i32
@@ -60,3 +94,10 @@ llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
}
// CHECK: @a3 = alias i32, addrspacecast (ptr @v1 to ptr addrspace(2))
+
+// ROUNDTRIP: llvm.mlir.global external @v1(0 : i32) {addr_space = 0 : i32} : i32
+// ROUNDTRIP: llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
+// ROUNDTRIP: %0 = llvm.mlir.addressof @v1 : !llvm.ptr
+// ROUNDTRIP: %1 = llvm.addrspacecast %0 : !llvm.ptr to !llvm.ptr<2>
+// ROUNDTRIP: llvm.return %1 : !llvm.ptr<2>
+// ROUNDTRIP: }
>From 3eb7a533fde675dcdfe55aaf6f5ee03d1e050b69 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Mon, 3 Feb 2025 16:22:54 -0800
Subject: [PATCH 10/21] Fix more nits and align linkage verification with LLVM
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 6 ++--
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 29 ++++++++++--------
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 32 +++++++++-----------
mlir/test/Dialect/LLVMIR/invalid.mlir | 2 +-
4 files changed, 35 insertions(+), 34 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 84b4829addac60..14f311a62ebb36 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1512,11 +1512,11 @@ def LLVM_AliasOp : LLVM_Op<"mlir.alias",
Region &getInitializerRegion() {
return getOperation()->getRegion(0);
}
- /// Return the initializer block. The initializer region always exist
+ /// Return the initializer block. The initializer region always exists
/// (differently from llvm.global) and it terminates with an `llvm.return`
/// op with the aliasee value.
- Block *getInitializerBlock() {
- return &getInitializerRegion().front();
+ Block &getInitializerBlock() {
+ return getInitializerRegion().front();
}
}];
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 1a8685a8a3e584..9c5c6aba238b85 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -2473,10 +2473,6 @@ void AliasOp::print(OpAsmPrinter &p) {
p << str << ' ';
}
p.printSymbolName(getSymName());
-
- // Note that the alignment attribute is printed using the
- // default syntax here, even though it is an inherent attribute
- // (as defined in https://mlir.llvm.org/docs/LangRef/#attributes)
p.printOptionalAttrDict((*this)->getAttrs(),
{SymbolTable::getSymbolAttrName(),
getAliasTypeAttrName(), getLinkageAttrName(),
@@ -2537,20 +2533,27 @@ LogicalResult AliasOp::verify() {
return emitOpError(
"expects type to be a valid element type for an LLVM global alias");
- if (getLinkage() == Linkage::Appending) {
- if (!llvm::isa<LLVMArrayType>(getType())) {
- return emitOpError() << "expected array type for '"
- << stringifyLinkage(Linkage::Appending)
- << "' linkage";
- }
+ // This matches LLVM IR verification logic, see llvm/lib/IR/Verifier.cpp
+ bool validAliasLinkage =
+ getLinkage() == Linkage::External || getLinkage() == Linkage::Internal ||
+ getLinkage() == Linkage::Private || getLinkage() == Linkage::Weak ||
+ getLinkage() == Linkage::Linkonce ||
+ getLinkage() == Linkage::LinkonceODR ||
+ getLinkage() == Linkage::AvailableExternally;
+
+ if (!validAliasLinkage) {
+ return emitOpError()
+ << "linkage must be private, internal, linkonce, weak, "
+ "linkonce_odr, "
+ "weak_odr, external or available_externally linkage!";
}
return success();
}
LogicalResult AliasOp::verifyRegions() {
- Block *b = getInitializerBlock();
- ReturnOp ret = cast<ReturnOp>(b->getTerminator());
+ Block &b = getInitializerBlock();
+ ReturnOp ret = cast<ReturnOp>(b.getTerminator());
if (ret.getNumOperands() == 0 ||
!isa<LLVM::LLVMPointerType>(ret.getOperand(0).getType()))
return emitOpError("initializer region must always return a pointer");
@@ -2559,7 +2562,7 @@ LogicalResult AliasOp::verifyRegions() {
if (ptrTy.getAddressSpace() != getAddrSpace())
return emitOpError("address space must match initializer returned one");
- for (Operation &op : *b) {
+ for (Operation &op : b) {
auto iface = dyn_cast<MemoryEffectOpInterface>(op);
if (!iface || !iface.hasNoEffect())
return op.emitError()
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 8fe9eeed02943c..31ac5345dcb3af 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1283,24 +1283,22 @@ LogicalResult ModuleTranslation::convertAliases() {
// have been created in LLVM IR because a global body may refer to another
// global alias. So all aliases need to be mapped first.
for (auto op : getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
- if (Block *initializer = op.getInitializerBlock()) {
- llvm::IRBuilder<> builder(llvmModule->getContext());
-
- for (mlir::Operation &op : initializer->without_terminator()) {
- if (failed(convertOperation(op, builder)))
- return emitError(op.getLoc(), "fail to convert alias initializer");
- auto *cst = dyn_cast<llvm::Constant>(lookupValue(op.getResult(0)));
- if (!cst)
- return emitError(op.getLoc(), "unemittable constant value");
- }
-
- ReturnOp ret = cast<ReturnOp>(initializer->getTerminator());
- llvm::Constant *cst =
- cast<llvm::Constant>(lookupValue(ret.getOperand(0)));
- assert(aliasesMapping.count(op));
- auto *alias = cast<llvm::GlobalAlias>(aliasesMapping[op]);
- alias->setAliasee(cst);
+ Block &initializer = op.getInitializerBlock();
+ llvm::IRBuilder<> builder(llvmModule->getContext());
+
+ for (mlir::Operation &op : initializer.without_terminator()) {
+ if (failed(convertOperation(op, builder)))
+ return emitError(op.getLoc(), "fail to convert alias initializer");
+ auto *cst = dyn_cast<llvm::Constant>(lookupValue(op.getResult(0)));
+ if (!cst)
+ return emitError(op.getLoc(), "unemittable constant value");
}
+
+ ReturnOp ret = cast<ReturnOp>(initializer.getTerminator());
+ llvm::Constant *cst = cast<llvm::Constant>(lookupValue(ret.getOperand(0)));
+ assert(aliasesMapping.count(op));
+ auto *alias = cast<llvm::GlobalAlias>(aliasesMapping[op]);
+ alias->setAliasee(cst);
}
for (auto op : getModuleBody(mlirModule).getOps<LLVM::AliasOp>())
diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir
index 0d5a418c0be7ae..2f5d84af552c80 100644
--- a/mlir/test/Dialect/LLVMIR/invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid.mlir
@@ -1716,7 +1716,7 @@ llvm.mlir.alias external @y {addr_space = 0 : i32} : !llvm.label {
// -----
-// expected-error at +1 {{expected array type for 'appending' linkage}}
+// expected-error at +1 {{linkage must be private, internal, linkonce, weak}}
llvm.mlir.alias appending @y2 {addr_space = 0 : i32} : i32 {
%0 = llvm.mlir.addressof @x : !llvm.ptr
llvm.return %0 : !llvm.ptr
>From f159dcc5a88e34920e5aaf9d79f666ec6af93b64 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Mon, 3 Feb 2025 16:28:36 -0800
Subject: [PATCH 11/21] Fix one more comment
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 14f311a62ebb36..07d296c2bbc773 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1507,14 +1507,11 @@ def LLVM_AliasOp : LLVM_Op<"mlir.alias",
Type getType() {
return getAliasType();
}
- /// Return the initializer region. This may be empty, but if it is not it
- /// terminates in an `llvm.return` op with the initializer value.
+ /// Return the initializer region. It's always present and terminates
+ /// with an `llvm.return` op with the initializer value.
Region &getInitializerRegion() {
return getOperation()->getRegion(0);
}
- /// Return the initializer block. The initializer region always exists
- /// (differently from llvm.global) and it terminates with an `llvm.return`
- /// op with the aliasee value.
Block &getInitializerBlock() {
return getInitializerRegion().front();
}
>From cf984ad134474042ecb52779a0653023aa165f12 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Mon, 3 Feb 2025 16:30:48 -0800
Subject: [PATCH 12/21] Update parse comment
---
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 9c5c6aba238b85..4ca33cd8d2a985 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -2495,8 +2495,6 @@ void AliasOp::print(OpAsmPrinter &p) {
// `(` attribute? `)`
// attribute-list? `:` type region
//
-// The type can be omitted for string attributes, in which case it will be
-// inferred from the value of the string as [strlen(value) x i8].
ParseResult AliasOp::parse(OpAsmParser &parser, OperationState &result) {
// Call into common parsing between GlobalOp and AliasOp.
if (parseCommonGlobalAndAlias<AliasOp>(parser, result).failed())
>From 77661e7e51d534ef3e7f987d682dac0fa6e25d1f Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Mon, 3 Feb 2025 17:44:51 -0800
Subject: [PATCH 13/21] Handle conversion for globals/aliases together since
they can reference each other
---
.../mlir/Target/LLVMIR/ModuleTranslation.h | 3 +-
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 80 +++++++++----------
2 files changed, 40 insertions(+), 43 deletions(-)
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
index 28bc3642eb73dc..78bfbdde27a51a 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
@@ -327,8 +327,7 @@ class ModuleTranslation {
LogicalResult convertFunctionSignatures();
LogicalResult convertFunctions();
LogicalResult convertComdats();
- LogicalResult convertGlobals();
- LogicalResult convertAliases();
+ LogicalResult convertGlobalsAndAliases();
LogicalResult convertOneFunction(LLVMFuncOp func);
LogicalResult convertBlockImpl(Block &bb, bool ignoreArguments,
llvm::IRBuilderBase &builder,
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 31ac5345dcb3af..a70fd570273735 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1028,12 +1028,20 @@ static void addRuntimePreemptionSpecifier(bool dsoLocalRequested,
gv->setDSOLocal(true);
}
-/// Create named global variables that correspond to llvm.mlir.global
-/// definitions. Convert llvm.global_ctors and global_dtors ops.
-LogicalResult ModuleTranslation::convertGlobals() {
+/// Handle conversion for both globals and global aliases.
+///
+/// - Create named global variables that correspond to llvm.mlir.global
+/// definitions, similarly Convert llvm.global_ctors and global_dtors ops.
+/// - Create global alias that correspond to llvm.mlir.alias.
+LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
// Mapping from compile unit to its respective set of global variables.
DenseMap<llvm::DICompileUnit *, SmallVector<llvm::Metadata *>> allGVars;
+ // First, create all global variables and global aliases in LLVM IR. A global
+ // or alias body may refer to another global/alias or itself, so all the
+ // mapping needs to happen prior to body conversion.
+
+ // Create all llvm::GlobalVariable
for (auto op : getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
llvm::Type *type = convertType(op.getType());
llvm::Constant *cst = nullptr;
@@ -1137,9 +1145,32 @@ LogicalResult ModuleTranslation::convertGlobals() {
}
}
- // Convert global variable bodies. This is done after all global variables
- // have been created in LLVM IR because a global body may refer to another
- // global or itself. So all global variables need to be mapped first.
+ // Create all llvm::GlobalAlias
+ for (auto op : getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
+ llvm::Type *type = convertType(op.getType());
+ llvm::Constant *cst = nullptr;
+ auto linkage = convertLinkageToLLVM(op.getLinkage());
+ llvm::Module &llvmMod = *llvmModule;
+
+ llvm::GlobalAlias *var = llvm::GlobalAlias::create(
+ type, op.getAddrSpace(), linkage, op.getSymName(), cst, &llvmMod);
+
+ var->setThreadLocalMode(op.getThreadLocal_()
+ ? llvm::GlobalAlias::GeneralDynamicTLSModel
+ : llvm::GlobalAlias::NotThreadLocal);
+
+ // Note there is no need to setup the comdat because GlobalAlias calls into
+ // the aliasee comdat information automatically.
+
+ if (op.getUnnamedAddr().has_value())
+ var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
+
+ var->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
+
+ aliasesMapping.try_emplace(op, var);
+ }
+
+ // Convert global variable bodies.
for (auto op : getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
if (Block *initializer = op.getInitializerBlock()) {
llvm::IRBuilder<> builder(llvmModule->getContext());
@@ -1250,38 +1281,7 @@ LogicalResult ModuleTranslation::convertGlobals() {
llvm::MDTuple::get(getLLVMContext(), globals));
}
- return success();
-}
-
-/// Convert aliases.
-LogicalResult ModuleTranslation::convertAliases() {
- for (auto op : getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
- llvm::Type *type = convertType(op.getType());
- llvm::Constant *cst = nullptr;
- auto linkage = convertLinkageToLLVM(op.getLinkage());
- llvm::Module &llvmMod = *llvmModule;
-
- llvm::GlobalAlias *var = llvm::GlobalAlias::create(
- type, op.getAddrSpace(), linkage, op.getSymName(), cst, &llvmMod);
-
- var->setThreadLocalMode(op.getThreadLocal_()
- ? llvm::GlobalAlias::GeneralDynamicTLSModel
- : llvm::GlobalAlias::NotThreadLocal);
-
- // Note there is no need to setup the comdat because GlobalAlias calls into
- // the aliasee comdat information automatically.
-
- if (op.getUnnamedAddr().has_value())
- var->setUnnamedAddr(convertUnnamedAddrToLLVM(*op.getUnnamedAddr()));
-
- var->setVisibility(convertVisibilityToLLVM(op.getVisibility_()));
-
- aliasesMapping.try_emplace(op, var);
- }
-
- // Convert global aliases. This is done after all global aliases
- // have been created in LLVM IR because a global body may refer to another
- // global alias. So all aliases need to be mapped first.
+ // Convert global alias bodies.
for (auto op : getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
Block &initializer = op.getInitializerBlock();
llvm::IRBuilder<> builder(llvmModule->getContext());
@@ -2112,9 +2112,7 @@ mlir::translateModuleToLLVMIR(Operation *module, llvm::LLVMContext &llvmContext,
return nullptr;
if (failed(translator.convertFunctionSignatures()))
return nullptr;
- if (failed(translator.convertGlobals()))
- return nullptr;
- if (failed(translator.convertAliases()))
+ if (failed(translator.convertGlobalsAndAliases()))
return nullptr;
if (failed(translator.createTBAAMetadata()))
return nullptr;
>From b669463bae72b2d019fc379b2534a440de556914 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Mon, 3 Feb 2025 18:29:56 -0800
Subject: [PATCH 14/21] Teach LLVM_AddressOfOp to work with alias symbols, fix
remaining bugs and add more testcases
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 14 +++++-
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 17 +++++--
.../LLVMIR/LLVMToLLVMIRTranslation.cpp | 20 +++++---
mlir/lib/Target/LLVMIR/ModuleImport.cpp | 8 ++++
mlir/test/Target/LLVMIR/Import/alias.ll | 28 +++++++++++
mlir/test/Target/LLVMIR/alias.mlir | 48 +++++++++++++++++++
6 files changed, 122 insertions(+), 13 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 07d296c2bbc773..76bce44fa95146 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1163,7 +1163,7 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
let arguments = (ins FlatSymbolRefAttr:$global_name);
let results = (outs LLVM_AnyPointer:$res);
- let summary = "Creates a pointer pointing to a global or a function";
+ let summary = "Creates a pointer pointing to a global, alias or a function";
let description = [{
Creates an SSA value containing a pointer to a global variable or constant
@@ -1208,6 +1208,14 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
build($_builder, $_state,
LLVM::LLVMPointerType::get($_builder.getContext()), func.getName());
$_state.addAttributes(attrs);
+ }]>,
+ OpBuilder<(ins "AliasOp":$alias,
+ CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs),
+ [{
+ build($_builder, $_state,
+ LLVM::LLVMPointerType::get($_builder.getContext(), alias.getAddrSpace()),
+ alias.getSymName());
+ $_state.addAttributes(attrs);
}]>
];
@@ -1218,6 +1226,10 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
/// Return the llvm.func operation that is referenced here.
LLVMFuncOp getFunction(SymbolTableCollection &symbolTable);
+
+ /// Return the llvm.mlir.alias operation that defined the value referenced
+ /// here.
+ AliasOp getAlias(SymbolTableCollection &symbolTable);
}];
let assemblyFormat = "$global_name attr-dict `:` qualified(type($res))";
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 4ca33cd8d2a985..22b72c6af6270b 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -2036,6 +2036,11 @@ LLVMFuncOp AddressOfOp::getFunction(SymbolTableCollection &symbolTable) {
symbolTable.lookupSymbolIn(parentLLVMModule(*this), getGlobalNameAttr()));
}
+AliasOp AddressOfOp::getAlias(SymbolTableCollection &symbolTable) {
+ return dyn_cast_or_null<AliasOp>(
+ symbolTable.lookupSymbolIn(parentLLVMModule(*this), getGlobalNameAttr()));
+}
+
LogicalResult
AddressOfOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
Operation *symbol =
@@ -2043,15 +2048,17 @@ AddressOfOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
auto global = dyn_cast_or_null<GlobalOp>(symbol);
auto function = dyn_cast_or_null<LLVMFuncOp>(symbol);
+ auto alias = dyn_cast_or_null<AliasOp>(symbol);
- if (!global && !function)
- return emitOpError(
- "must reference a global defined by 'llvm.mlir.global' or 'llvm.func'");
+ if (!global && !function && !alias)
+ return emitOpError("must reference a global defined by 'llvm.mlir.global', "
+ "'llvm.mlir.alias' or 'llvm.func'");
LLVMPointerType type = getType();
- if (global && global.getAddrSpace() != type.getAddressSpace())
+ if ((global && global.getAddrSpace() != type.getAddressSpace()) ||
+ (alias && alias.getAddrSpace() != type.getAddressSpace()))
return emitOpError("pointer address space must match address space of the "
- "referenced global");
+ "referenced global or alias");
return success();
}
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 2084e527773ca8..14832ea3725b6a 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -447,15 +447,21 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
addressOfOp.getGlobal(moduleTranslation.symbolTable());
LLVM::LLVMFuncOp function =
addressOfOp.getFunction(moduleTranslation.symbolTable());
+ LLVM::AliasOp alias = addressOfOp.getAlias(moduleTranslation.symbolTable());
// The verifier should not have allowed this.
- assert((global || function) &&
- "referencing an undefined global or function");
-
- moduleTranslation.mapValue(
- addressOfOp.getResult(),
- global ? moduleTranslation.lookupGlobal(global)
- : moduleTranslation.lookupFunction(function.getName()));
+ assert((global || function || alias) &&
+ "referencing an undefined global, function or alias");
+
+ llvm::Value *llvmValue = nullptr;
+ if (global)
+ llvmValue = moduleTranslation.lookupGlobal(global);
+ else if (alias)
+ llvmValue = moduleTranslation.lookupAlias(alias);
+ else
+ llvmValue = moduleTranslation.lookupFunction(function.getName());
+
+ moduleTranslation.mapValue(addressOfOp.getResult(), llvmValue);
return success();
}
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 0c6bace4e762da..c8e1fbe0c87be2 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1231,6 +1231,14 @@ FailureOr<Value> ModuleImport::convertConstant(llvm::Constant *constant) {
return builder.create<AddressOfOp>(loc, type, symbolRef).getResult();
}
+ // Convert global alias accesses.
+ if (auto *globalAliasObj = dyn_cast<llvm::GlobalAlias>(constant)) {
+ Type type = convertType(globalAliasObj->getType());
+ StringRef aliaseeName = globalAliasObj->getName();
+ FlatSymbolRefAttr symbolRef = FlatSymbolRefAttr::get(context, aliaseeName);
+ return builder.create<AddressOfOp>(loc, type, symbolRef).getResult();
+ }
+
// Convert constant expressions.
if (auto *constExpr = dyn_cast<llvm::ConstantExpr>(constant)) {
// Convert the constant expression to a temporary LLVM instruction and
diff --git a/mlir/test/Target/LLVMIR/Import/alias.ll b/mlir/test/Target/LLVMIR/Import/alias.ll
index c04413c19c1c39..81fe5993010600 100644
--- a/mlir/test/Target/LLVMIR/Import/alias.ll
+++ b/mlir/test/Target/LLVMIR/Import/alias.ll
@@ -51,3 +51,31 @@ entry:
; CHECK: %3 = llvm.add %2, %0 : i64
; CHECK: %4 = llvm.inttoptr %3 : i64 to !llvm.ptr
; CHECK: llvm.return %4 : !llvm.ptr
+
+ at g1 = private global i32 0
+ at g2 = internal constant ptr @a1
+ at g3 = internal constant ptr @a2
+ at a1 = private alias i32, ptr @g1
+ at a2 = private alias ptr, ptr @a1
+
+; CHECK: llvm.mlir.alias private @a1 {addr_space = 0 : i32, dso_local} : i32 {
+; CHECK: %0 = llvm.mlir.addressof @g1 : !llvm.ptr
+; CHECK: llvm.return %0 : !llvm.ptr
+; CHECK: }
+; CHECK: llvm.mlir.alias private @a2 {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+; CHECK: %0 = llvm.mlir.addressof @g1 : !llvm.ptr
+; CHECK: %1 = llvm.mlir.addressof @a1 : !llvm.ptr
+; CHECK: llvm.return %1 : !llvm.ptr
+; CHECK: }
+
+; CHECK: llvm.mlir.global internal constant @g2() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+; CHECK: %0 = llvm.mlir.addressof @g1 : !llvm.ptr
+; CHECK: %1 = llvm.mlir.addressof @a1 : !llvm.ptr
+; CHECK: llvm.return %1 : !llvm.ptr
+; CHECK: }
+; CHECK: llvm.mlir.global internal constant @g3() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+; CHECK: %0 = llvm.mlir.addressof @g1 : !llvm.ptr
+; CHECK: %1 = llvm.mlir.addressof @a1 : !llvm.ptr
+; CHECK: %2 = llvm.mlir.addressof @a2 : !llvm.ptr
+; CHECK: llvm.return %2 : !llvm.ptr
+; CHECK: }
\ No newline at end of file
diff --git a/mlir/test/Target/LLVMIR/alias.mlir b/mlir/test/Target/LLVMIR/alias.mlir
index 6cd33270ee7d77..824765dbb4950d 100644
--- a/mlir/test/Target/LLVMIR/alias.mlir
+++ b/mlir/test/Target/LLVMIR/alias.mlir
@@ -101,3 +101,51 @@ llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
// ROUNDTRIP: %1 = llvm.addrspacecast %0 : !llvm.ptr to !llvm.ptr<2>
// ROUNDTRIP: llvm.return %1 : !llvm.ptr<2>
// ROUNDTRIP: }
+
+// -----
+
+llvm.mlir.global private @g1(0 : i32) {addr_space = 0 : i32, dso_local} : i32
+
+llvm.mlir.alias private @a1 {addr_space = 0 : i32, dso_local} : i32 {
+ %0 = llvm.mlir.addressof @g1 : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+llvm.mlir.global internal constant @g2() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+ %0 = llvm.mlir.addressof @a1 : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+llvm.mlir.alias private @a2 {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+ %0 = llvm.mlir.addressof @a1 : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+llvm.mlir.global internal constant @g3() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+ %0 = llvm.mlir.addressof @a2 : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+// CHECK: @g1 = private global i32 0
+// CHECK: @g2 = internal constant ptr @a1
+// CHECK: @g3 = internal constant ptr @a2
+// CHECK: @a1 = private alias i32, ptr @g1
+// CHECK: @a2 = private alias ptr, ptr @a1
+
+// ROUNDTRIP: llvm.mlir.global private @g1(0 : i32) {addr_space = 0 : i32, dso_local} : i32
+// ROUNDTRIP: llvm.mlir.alias private @a1 {addr_space = 0 : i32, dso_local} : i32 {
+// ROUNDTRIP: %0 = llvm.mlir.addressof @g1 : !llvm.ptr
+// ROUNDTRIP: llvm.return %0 : !llvm.ptr
+// ROUNDTRIP: }
+// ROUNDTRIP: llvm.mlir.global internal constant @g2() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+// ROUNDTRIP: %0 = llvm.mlir.addressof @a1 : !llvm.ptr
+// ROUNDTRIP: llvm.return %0 : !llvm.ptr
+// ROUNDTRIP: }
+// ROUNDTRIP: llvm.mlir.alias private @a2 {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+// ROUNDTRIP: %0 = llvm.mlir.addressof @a1 : !llvm.ptr
+// ROUNDTRIP: llvm.return %0 : !llvm.ptr
+// ROUNDTRIP: }
+// ROUNDTRIP: llvm.mlir.global internal constant @g3() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+// ROUNDTRIP: %0 = llvm.mlir.addressof @a2 : !llvm.ptr
+// ROUNDTRIP: llvm.return %0 : !llvm.ptr
+// ROUNDTRIP: }
\ No newline at end of file
>From 644424d10c239784f0e1c54c9f84c7e780557092 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Tue, 4 Feb 2025 11:00:18 -0800
Subject: [PATCH 15/21] Improve LLVM_AddressOfOp description doc
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 76bce44fa95146..43bf6c1b8e9537 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1166,9 +1166,9 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
let summary = "Creates a pointer pointing to a global, alias or a function";
let description = [{
- Creates an SSA value containing a pointer to a global variable or constant
- defined by `llvm.mlir.global`. The global value can be defined after its
- first referenced. If the global value is a constant, storing into it is not
+ Creates an SSA value containing a pointer to a global value (function,
+ variable or alias). The global value can be defined after its first
+ referenced. If the global value is a constant, storing into it is not
allowed.
Examples:
@@ -1186,10 +1186,19 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
// The function address can be used for indirect calls.
llvm.call %2() : !llvm.ptr, () -> ()
+
+ // Get the address of an aliased global.
+ %3 = llvm.mlir.addressof @const_alias : !llvm.ptr
}
// Define the global.
llvm.mlir.global @const(42 : i32) : i32
+
+ // Define an alias.
+ llvm.mlir.alias @const_alias : i32 {
+ %0 = llvm.mlir.addressof @const : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+ }
```
}];
>From 0d181eeee915c416eb561bfc79e245cf12c86def Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Tue, 4 Feb 2025 11:23:00 -0800
Subject: [PATCH 16/21] More tablegen fixes, new test file in Dialect
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 5 +-
mlir/test/Dialect/LLVMIR/alias.mlir | 127 ++++++++++++++++++++
mlir/test/Target/LLVMIR/Import/alias.ll | 6 +-
mlir/test/Target/LLVMIR/alias.mlir | 59 ---------
4 files changed, 132 insertions(+), 65 deletions(-)
create mode 100644 mlir/test/Dialect/LLVMIR/alias.mlir
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 43bf6c1b8e9537..dbf17fa480082f 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1465,7 +1465,7 @@ def LLVM_GlobalDtorsOp : LLVM_Op<"mlir.global_dtors", [
}
def LLVM_AliasOp : LLVM_Op<"mlir.alias",
- [IsolatedFromAbove, SingleBlockImplicitTerminator<"ReturnOp">, Symbol]> {
+ [IsolatedFromAbove, SingleBlockWithTerminator<"ReturnOp">, Symbol]> {
let arguments = (ins
TypeAttr:$alias_type,
StrAttr:$sym_name,
@@ -1474,7 +1474,6 @@ def LLVM_AliasOp : LLVM_Op<"mlir.alias",
UnitAttr:$thread_local_,
DefaultValuedAttr<ConfinedAttr<I32Attr, [IntNonNegative]>, "0">:$addr_space,
OptionalAttr<UnnamedAddr>:$unnamed_addr,
- OptionalAttr<StrAttr>:$section,
DefaultValuedAttr<Visibility, "mlir::LLVM::Visibility::Default">:$visibility_
);
let summary = "LLVM dialect alias.";
@@ -1512,7 +1511,7 @@ def LLVM_AliasOp : LLVM_Op<"mlir.alias",
}
```
}];
- let regions = (region AnyRegion:$initializer);
+ let regions = (region SizedRegion<1>:$initializer);
let builders = [
OpBuilder<(ins "Type":$type, "Linkage":$linkage,
diff --git a/mlir/test/Dialect/LLVMIR/alias.mlir b/mlir/test/Dialect/LLVMIR/alias.mlir
new file mode 100644
index 00000000000000..1f30f73811958a
--- /dev/null
+++ b/mlir/test/Dialect/LLVMIR/alias.mlir
@@ -0,0 +1,127 @@
+// RUN: mlir-opt %s -split-input-file | FileCheck %s
+
+llvm.func internal @callee() -> !llvm.ptr attributes {dso_local} {
+ %0 = llvm.mlir.zero : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
+ %0 = llvm.mlir.addressof @callee : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
+ %0 = llvm.mlir.addressof @callee : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+// CHECK: llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
+// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @callee : !llvm.ptr
+// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
+// CHECK: }
+// CHECK: llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
+// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @callee : !llvm.ptr
+// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
+// CHECK: }
+
+// -----
+
+llvm.mlir.global external @zed(42 : i32) {addr_space = 0 : i32} : i32
+
+llvm.mlir.alias external @foo {addr_space = 0 : i32} : i32 {
+ %0 = llvm.mlir.addressof @zed : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
+ %0 = llvm.mlir.addressof @zed : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+// CHECK: llvm.mlir.alias external @foo {addr_space = 0 : i32} : i32 {
+// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @zed : !llvm.ptr
+// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
+// CHECK: }
+// CHECK: llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
+// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @zed : !llvm.ptr
+// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
+// CHECK: }
+
+// -----
+
+llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32>
+
+llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32> {
+ %0 = llvm.mlir.constant(1234 : i64) : i64
+ %1 = llvm.mlir.addressof @glob.private : !llvm.ptr
+ %2 = llvm.ptrtoint %1 : !llvm.ptr to i64
+ %3 = llvm.add %2, %0 : i64
+ %4 = llvm.inttoptr %3 : i64 to !llvm.ptr
+ llvm.return %4 : !llvm.ptr
+}
+
+// CHECK: llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32>
+// CHECK: llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32> {
+// CHECK: %[[CST:.*]] = llvm.mlir.constant(1234 : i64) : i64
+// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @glob.private : !llvm.ptr
+// CHECK: %[[INTADDR:.*]] = llvm.ptrtoint %[[ADDR]] : !llvm.ptr to i64
+// CHECK: %[[BACKTOPTR:.*]] = llvm.add %[[INTADDR]], %[[CST]] : i64
+// CHECK: %[[RET_ADDR:.*]] = llvm.inttoptr %[[BACKTOPTR]] : i64 to !llvm.ptr
+// CHECK: llvm.return %[[RET_ADDR]] : !llvm.ptr
+// CHECK: }
+
+// -----
+
+llvm.mlir.global external @v1(0 : i32) {addr_space = 0 : i32} : i32
+llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
+ %0 = llvm.mlir.addressof @v1 : !llvm.ptr
+ %1 = llvm.addrspacecast %0 : !llvm.ptr to !llvm.ptr<2>
+ llvm.return %1 : !llvm.ptr<2>
+}
+
+// CHECK: llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
+// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @v1 : !llvm.ptr
+// CHECK: %1 = llvm.addrspacecast %[[ADDR]] : !llvm.ptr to !llvm.ptr<2>
+// CHECK: llvm.return %1 : !llvm.ptr<2>
+// CHECK: }
+
+// -----
+
+llvm.mlir.global private @g1(0 : i32) {addr_space = 0 : i32, dso_local} : i32
+
+llvm.mlir.alias private @a1 {addr_space = 0 : i32, dso_local} : i32 {
+ %0 = llvm.mlir.addressof @g1 : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+llvm.mlir.global internal constant @g2() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+ %0 = llvm.mlir.addressof @a1 : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+llvm.mlir.alias private @a2 {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+ %0 = llvm.mlir.addressof @a1 : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+llvm.mlir.global internal constant @g3() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+ %0 = llvm.mlir.addressof @a2 : !llvm.ptr
+ llvm.return %0 : !llvm.ptr
+}
+
+// CHECK: llvm.mlir.alias private @a1 {addr_space = 0 : i32, dso_local} : i32 {
+// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @g1 : !llvm.ptr
+// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
+// CHECK: }
+// CHECK: llvm.mlir.global internal constant @g2() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @a1 : !llvm.ptr
+// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
+// CHECK: }
+// CHECK: llvm.mlir.alias private @a2 {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @a1 : !llvm.ptr
+// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
+// CHECK: }
+// CHECK: llvm.mlir.global internal constant @g3() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @a2 : !llvm.ptr
+// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
+// CHECK: }
diff --git a/mlir/test/Target/LLVMIR/Import/alias.ll b/mlir/test/Target/LLVMIR/Import/alias.ll
index 81fe5993010600..49c69017ea765a 100644
--- a/mlir/test/Target/LLVMIR/Import/alias.ll
+++ b/mlir/test/Target/LLVMIR/Import/alias.ll
@@ -34,9 +34,9 @@ entry:
; CHECK: }
@some_name = constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr null] }
- at _ZTV1D = alias { [3 x ptr] }, ptr @some_name
+ at vtable = alias { [3 x ptr] }, ptr @some_name
-; CHECK: llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
+; CHECK: llvm.mlir.alias external @vtable {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
; CHECK: %0 = llvm.mlir.addressof @some_name : !llvm.ptr
; CHECK: llvm.return %0 : !llvm.ptr
; CHECK: }
@@ -78,4 +78,4 @@ entry:
; CHECK: %1 = llvm.mlir.addressof @a1 : !llvm.ptr
; CHECK: %2 = llvm.mlir.addressof @a2 : !llvm.ptr
; CHECK: llvm.return %2 : !llvm.ptr
-; CHECK: }
\ No newline at end of file
+; CHECK: }
diff --git a/mlir/test/Target/LLVMIR/alias.mlir b/mlir/test/Target/LLVMIR/alias.mlir
index 824765dbb4950d..d3a2c80156004a 100644
--- a/mlir/test/Target/LLVMIR/alias.mlir
+++ b/mlir/test/Target/LLVMIR/alias.mlir
@@ -1,5 +1,4 @@
// RUN: mlir-translate -mlir-to-llvmir %s -split-input-file | FileCheck %s
-// RUN: mlir-opt %s -split-input-file | FileCheck -check-prefix=ROUNDTRIP %s
llvm.func internal @callee() -> !llvm.ptr attributes {dso_local} {
%0 = llvm.mlir.zero : !llvm.ptr
@@ -19,19 +18,6 @@ llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3
// CHECK: @foo_alias = alias ptr, ptr @callee
// CHECK: @_ZTV1D = alias { [3 x ptr] }, ptr @callee
-// ROUNDTRIP: llvm.func internal @callee() -> !llvm.ptr attributes {dso_local} {
-// ROUNDTRIP: %0 = llvm.mlir.zero : !llvm.ptr
-// ROUNDTRIP: llvm.return %0 : !llvm.ptr
-// ROUNDTRIP: }
-// ROUNDTRIP: llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
-// ROUNDTRIP: %0 = llvm.mlir.addressof @callee : !llvm.ptr
-// ROUNDTRIP: llvm.return %0 : !llvm.ptr
-// ROUNDTRIP: }
-// ROUNDTRIP: llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
-// ROUNDTRIP: %0 = llvm.mlir.addressof @callee : !llvm.ptr
-// ROUNDTRIP: llvm.return %0 : !llvm.ptr
-// ROUNDTRIP: }
-
// -----
llvm.mlir.global external @zed(42 : i32) {addr_space = 0 : i32} : i32
@@ -49,16 +35,6 @@ llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
// CHECK: @foo = alias i32, ptr @zed
// CHECK: @foo2 = alias i16, ptr @zed
-// ROUNDTRIP: llvm.mlir.global external @zed(42 : i32) {addr_space = 0 : i32} : i32
-// ROUNDTRIP: llvm.mlir.alias external @foo {addr_space = 0 : i32} : i32 {
-// ROUNDTRIP: %0 = llvm.mlir.addressof @zed : !llvm.ptr
-// ROUNDTRIP: llvm.return %0 : !llvm.ptr
-// ROUNDTRIP: }
-// ROUNDTRIP: llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
-// ROUNDTRIP: %0 = llvm.mlir.addressof @zed : !llvm.ptr
-// ROUNDTRIP: llvm.return %0 : !llvm.ptr
-// ROUNDTRIP: }
-
// -----
llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32>
@@ -74,16 +50,6 @@ llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !l
// CHECK: @glob = linkonce_odr hidden alias [32 x i32], inttoptr (i64 add (i64 ptrtoint (ptr @glob.private to i64), i64 1234) to ptr)
-// ROUNDTRIP: llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32>
-// ROUNDTRIP: llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32> {
-// ROUNDTRIP: %0 = llvm.mlir.constant(1234 : i64) : i64
-// ROUNDTRIP: %1 = llvm.mlir.addressof @glob.private : !llvm.ptr
-// ROUNDTRIP: %2 = llvm.ptrtoint %1 : !llvm.ptr to i64
-// ROUNDTRIP: %3 = llvm.add %2, %0 : i64
-// ROUNDTRIP: %4 = llvm.inttoptr %3 : i64 to !llvm.ptr
-// ROUNDTRIP: llvm.return %4 : !llvm.ptr
-// ROUNDTRIP: }
-
// -----
llvm.mlir.global external @v1(0 : i32) {addr_space = 0 : i32} : i32
@@ -95,13 +61,6 @@ llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
// CHECK: @a3 = alias i32, addrspacecast (ptr @v1 to ptr addrspace(2))
-// ROUNDTRIP: llvm.mlir.global external @v1(0 : i32) {addr_space = 0 : i32} : i32
-// ROUNDTRIP: llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
-// ROUNDTRIP: %0 = llvm.mlir.addressof @v1 : !llvm.ptr
-// ROUNDTRIP: %1 = llvm.addrspacecast %0 : !llvm.ptr to !llvm.ptr<2>
-// ROUNDTRIP: llvm.return %1 : !llvm.ptr<2>
-// ROUNDTRIP: }
-
// -----
llvm.mlir.global private @g1(0 : i32) {addr_space = 0 : i32, dso_local} : i32
@@ -131,21 +90,3 @@ llvm.mlir.global internal constant @g3() {addr_space = 0 : i32, dso_local} : !ll
// CHECK: @g3 = internal constant ptr @a2
// CHECK: @a1 = private alias i32, ptr @g1
// CHECK: @a2 = private alias ptr, ptr @a1
-
-// ROUNDTRIP: llvm.mlir.global private @g1(0 : i32) {addr_space = 0 : i32, dso_local} : i32
-// ROUNDTRIP: llvm.mlir.alias private @a1 {addr_space = 0 : i32, dso_local} : i32 {
-// ROUNDTRIP: %0 = llvm.mlir.addressof @g1 : !llvm.ptr
-// ROUNDTRIP: llvm.return %0 : !llvm.ptr
-// ROUNDTRIP: }
-// ROUNDTRIP: llvm.mlir.global internal constant @g2() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
-// ROUNDTRIP: %0 = llvm.mlir.addressof @a1 : !llvm.ptr
-// ROUNDTRIP: llvm.return %0 : !llvm.ptr
-// ROUNDTRIP: }
-// ROUNDTRIP: llvm.mlir.alias private @a2 {addr_space = 0 : i32, dso_local} : !llvm.ptr {
-// ROUNDTRIP: %0 = llvm.mlir.addressof @a1 : !llvm.ptr
-// ROUNDTRIP: llvm.return %0 : !llvm.ptr
-// ROUNDTRIP: }
-// ROUNDTRIP: llvm.mlir.global internal constant @g3() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
-// ROUNDTRIP: %0 = llvm.mlir.addressof @a2 : !llvm.ptr
-// ROUNDTRIP: llvm.return %0 : !llvm.ptr
-// ROUNDTRIP: }
\ No newline at end of file
>From 3932b160e22b6befabd7a0e6ab45501e31613f9b Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Tue, 4 Feb 2025 11:59:38 -0800
Subject: [PATCH 17/21] Address more review comments
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 2 +-
.../mlir/Target/LLVMIR/ModuleTranslation.h | 6 +++
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 41 ++++++++++---------
.../LLVMIR/LLVMToLLVMIRTranslation.cpp | 2 +-
mlir/lib/Target/LLVMIR/ModuleImport.cpp | 2 -
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 15 +++----
mlir/test/Dialect/LLVMIR/invalid.mlir | 4 +-
7 files changed, 37 insertions(+), 35 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index dbf17fa480082f..3b6f78ee3a4a4e 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1465,7 +1465,7 @@ def LLVM_GlobalDtorsOp : LLVM_Op<"mlir.global_dtors", [
}
def LLVM_AliasOp : LLVM_Op<"mlir.alias",
- [IsolatedFromAbove, SingleBlockWithTerminator<"ReturnOp">, Symbol]> {
+ [IsolatedFromAbove, SingleBlockImplicitTerminator<"ReturnOp">, Symbol]> {
let arguments = (ins
TypeAttr:$alias_type,
StrAttr:$sym_name,
diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
index 78bfbdde27a51a..ec6182fb34413f 100644
--- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
+++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
@@ -327,6 +327,12 @@ class ModuleTranslation {
LogicalResult convertFunctionSignatures();
LogicalResult convertFunctions();
LogicalResult convertComdats();
+
+ /// Handle conversion for both globals and global aliases.
+ ///
+ /// - Create named global variables that correspond to llvm.mlir.global
+ /// definitions, similarly Convert llvm.global_ctors and global_dtors ops.
+ /// - Create global alias that correspond to llvm.mlir.alias.
LogicalResult convertGlobalsAndAliases();
LogicalResult convertOneFunction(LLVMFuncOp func);
LogicalResult convertBlockImpl(Block &bb, bool ignoreArguments,
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 22b72c6af6270b..a896f05a9ff5d3 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -2195,6 +2195,8 @@ static LogicalResult verifyComdat(Operation *op,
return success();
}
+/// Parse common attributes that might show up in the same order in both
+/// GlobalOp and AliasOp.
template <typename OpType>
static ParseResult parseCommonGlobalAndAlias(OpAsmParser &parser,
OperationState &result) {
@@ -2474,7 +2476,7 @@ void AliasOp::print(OpAsmPrinter &p) {
p << visibility << ' ';
if (getThreadLocal_())
p << "thread_local ";
- if (auto unnamedAddr = getUnnamedAddr()) {
+ if (std::optional<mlir::LLVM::UnnamedAddr> unnamedAddr = getUnnamedAddr()) {
StringRef str = stringifyUnnamedAddr(*unnamedAddr);
if (!str.empty())
p << str << ' ';
@@ -2486,14 +2488,10 @@ void AliasOp::print(OpAsmPrinter &p) {
getUnnamedAddrAttrName(), getThreadLocal_AttrName(),
getVisibility_AttrName(), getUnnamedAddrAttrName()});
- // Print the trailing type
- p << " : " << getType();
-
- Region &initializer = getInitializerRegion();
- if (!initializer.empty()) {
- p << ' ';
- p.printRegion(initializer, /*printEntryBlockArgs=*/false);
- }
+ // Print the trailing type.
+ p << " : " << getType() << ' ';
+ // Print the initializer region.
+ p.printRegion(getInitializerRegion(), /*printEntryBlockArgs=*/false);
}
// operation ::= `llvm.mlir.alias` linkage? visibility?
@@ -2539,18 +2537,21 @@ LogicalResult AliasOp::verify() {
"expects type to be a valid element type for an LLVM global alias");
// This matches LLVM IR verification logic, see llvm/lib/IR/Verifier.cpp
- bool validAliasLinkage =
- getLinkage() == Linkage::External || getLinkage() == Linkage::Internal ||
- getLinkage() == Linkage::Private || getLinkage() == Linkage::Weak ||
- getLinkage() == Linkage::Linkonce ||
- getLinkage() == Linkage::LinkonceODR ||
- getLinkage() == Linkage::AvailableExternally;
-
- if (!validAliasLinkage) {
+ switch (getLinkage()) {
+ case Linkage::External:
+ case Linkage::Internal:
+ case Linkage::Private:
+ case Linkage::Weak:
+ case Linkage::Linkonce:
+ case Linkage::LinkonceODR:
+ case Linkage::AvailableExternally:
+ break;
+ default:
return emitOpError()
- << "linkage must be private, internal, linkonce, weak, "
- "linkonce_odr, "
- "weak_odr, external or available_externally linkage!";
+ << "'" << stringifyLinkage(getLinkage())
+ << "' linkage not supported in aliases, available options: private, "
+ "internal, linkonce, weak, linkonce_odr, weak_odr, external or "
+ "available_externally";
}
return success();
diff --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 14832ea3725b6a..3afea87ca92c12 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -451,7 +451,7 @@ convertOperationImpl(Operation &opInst, llvm::IRBuilderBase &builder,
// The verifier should not have allowed this.
assert((global || function || alias) &&
- "referencing an undefined global, function or alias");
+ "referencing an undefined global, function, or alias");
llvm::Value *llvmValue = nullptr;
if (global)
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index c8e1fbe0c87be2..c5e0af1edce146 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -991,8 +991,6 @@ LogicalResult ModuleImport::convertAlias(llvm::GlobalAlias *alias) {
if (alias->hasAtLeastLocalUnnamedAddr()) {
aliasOp.setUnnamedAddr(convertUnnamedAddrFromLLVM(alias->getUnnamedAddr()));
}
- if (alias->hasSection())
- aliasOp.setSection(alias->getSection());
aliasOp.setVisibility_(convertVisibilityFromLLVM(alias->getVisibility()));
return success();
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index a70fd570273735..13352ab43cafa3 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1028,11 +1028,6 @@ static void addRuntimePreemptionSpecifier(bool dsoLocalRequested,
gv->setDSOLocal(true);
}
-/// Handle conversion for both globals and global aliases.
-///
-/// - Create named global variables that correspond to llvm.mlir.global
-/// definitions, similarly Convert llvm.global_ctors and global_dtors ops.
-/// - Create global alias that correspond to llvm.mlir.alias.
LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
// Mapping from compile unit to its respective set of global variables.
DenseMap<llvm::DICompileUnit *, SmallVector<llvm::Metadata *>> allGVars;
@@ -1149,7 +1144,8 @@ LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
for (auto op : getModuleBody(mlirModule).getOps<LLVM::AliasOp>()) {
llvm::Type *type = convertType(op.getType());
llvm::Constant *cst = nullptr;
- auto linkage = convertLinkageToLLVM(op.getLinkage());
+ llvm::GlobalValue::LinkageTypes linkage =
+ convertLinkageToLLVM(op.getLinkage());
llvm::Module &llvmMod = *llvmModule;
llvm::GlobalAlias *var = llvm::GlobalAlias::create(
@@ -1289,13 +1285,12 @@ LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
for (mlir::Operation &op : initializer.without_terminator()) {
if (failed(convertOperation(op, builder)))
return emitError(op.getLoc(), "fail to convert alias initializer");
- auto *cst = dyn_cast<llvm::Constant>(lookupValue(op.getResult(0)));
- if (!cst)
+ if (!isa<llvm::Constant>(lookupValue(op.getResult(0))))
return emitError(op.getLoc(), "unemittable constant value");
}
- ReturnOp ret = cast<ReturnOp>(initializer.getTerminator());
- llvm::Constant *cst = cast<llvm::Constant>(lookupValue(ret.getOperand(0)));
+ auto ret = cast<ReturnOp>(initializer.getTerminator());
+ auto *cst = cast<llvm::Constant>(lookupValue(ret.getOperand(0)));
assert(aliasesMapping.count(op));
auto *alias = cast<llvm::GlobalAlias>(aliasesMapping[op]);
alias->setAliasee(cst);
diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir
index 2f5d84af552c80..bff3dc25880f0f 100644
--- a/mlir/test/Dialect/LLVMIR/invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid.mlir
@@ -1716,7 +1716,9 @@ llvm.mlir.alias external @y {addr_space = 0 : i32} : !llvm.label {
// -----
-// expected-error at +1 {{linkage must be private, internal, linkonce, weak}}
+llvm.mlir.global external @x(42 : i32) {addr_space = 0 : i32} : i32
+
+// expected-error at +1 {{linkage not supported in aliases, available options}}
llvm.mlir.alias appending @y2 {addr_space = 0 : i32} : i32 {
%0 = llvm.mlir.addressof @x : !llvm.ptr
llvm.return %0 : !llvm.ptr
>From d8bd0ab76c920a0a5519e7e644841b08dcb6c19b Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Tue, 4 Feb 2025 12:01:42 -0800
Subject: [PATCH 18/21] More split-input-file love
---
mlir/test/Target/LLVMIR/Import/alias.ll | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/mlir/test/Target/LLVMIR/Import/alias.ll b/mlir/test/Target/LLVMIR/Import/alias.ll
index 49c69017ea765a..49c331eb2994fb 100644
--- a/mlir/test/Target/LLVMIR/Import/alias.ll
+++ b/mlir/test/Target/LLVMIR/Import/alias.ll
@@ -1,4 +1,4 @@
-; RUN: mlir-translate --import-llvm %s | FileCheck %s
+; RUN: mlir-translate --import-llvm %s -split-input-file | FileCheck %s
@foo_alias = alias ptr, ptr @callee
@@ -12,6 +12,8 @@ entry:
ret ptr null
}
+; -----
+
@zed = global i32 42
@foo = alias i32, ptr @zed
@foo2 = alias i16, ptr @zed
@@ -25,6 +27,8 @@ entry:
; CHECK: llvm.return %0 : !llvm.ptr
; CHECK: }
+; -----
+
@v1 = global i32 0
@a3 = alias i32, addrspacecast (ptr @v1 to ptr addrspace(2))
; CHECK: llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
@@ -33,6 +37,8 @@ entry:
; CHECK: llvm.return %1 : !llvm.ptr<2>
; CHECK: }
+; -----
+
@some_name = constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr null] }
@vtable = alias { [3 x ptr] }, ptr @some_name
@@ -41,6 +47,8 @@ entry:
; CHECK: llvm.return %0 : !llvm.ptr
; CHECK: }
+; -----
+
@glob.private = private constant [32 x i32] zeroinitializer
@glob = linkonce_odr hidden alias [32 x i32], inttoptr (i64 add (i64 ptrtoint (ptr @glob.private to i64), i64 1234) to ptr)
@@ -52,6 +60,8 @@ entry:
; CHECK: %4 = llvm.inttoptr %3 : i64 to !llvm.ptr
; CHECK: llvm.return %4 : !llvm.ptr
+; -----
+
@g1 = private global i32 0
@g2 = internal constant ptr @a1
@g3 = internal constant ptr @a2
>From 8683355144de69b1c8f070d8cf16c2552879f411 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Tue, 4 Feb 2025 15:59:11 -0800
Subject: [PATCH 19/21] Fix multiple printing of addressofs in init bodies
---
mlir/lib/Target/LLVMIR/ModuleImport.cpp | 2 +-
mlir/test/Target/LLVMIR/Import/alias.ll | 61 ++++++++++++-------------
2 files changed, 30 insertions(+), 33 deletions(-)
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index c5e0af1edce146..41658e7df5a7fc 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -1133,7 +1133,7 @@ ModuleImport::getConstantsToConvert(llvm::Constant *constant) {
llvm::Constant *current = workList.back();
// References of global objects are just pointers to the object. Avoid
// walking the elements of these here.
- if (isa<llvm::GlobalObject>(current)) {
+ if (isa<llvm::GlobalObject>(current) || isa<llvm::GlobalAlias>(current)) {
orderedSet.insert(current);
workList.pop_back();
continue;
diff --git a/mlir/test/Target/LLVMIR/Import/alias.ll b/mlir/test/Target/LLVMIR/Import/alias.ll
index 49c331eb2994fb..4142f12393ce3b 100644
--- a/mlir/test/Target/LLVMIR/Import/alias.ll
+++ b/mlir/test/Target/LLVMIR/Import/alias.ll
@@ -3,8 +3,8 @@
@foo_alias = alias ptr, ptr @callee
; CHECK: llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
-; CHECK: %0 = llvm.mlir.addressof @callee : !llvm.ptr
-; CHECK: llvm.return %0 : !llvm.ptr
+; CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @callee : !llvm.ptr
+; CHECK: llvm.return %[[ADDR]] : !llvm.ptr
; CHECK: }
define internal ptr @callee() {
@@ -19,12 +19,12 @@ entry:
@foo2 = alias i16, ptr @zed
; CHECK: llvm.mlir.alias external @foo {addr_space = 0 : i32} : i32 {
-; CHECK: %0 = llvm.mlir.addressof @zed : !llvm.ptr
-; CHECK: llvm.return %0 : !llvm.ptr
+; CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @zed : !llvm.ptr
+; CHECK: llvm.return %[[ADDR]] : !llvm.ptr
; CHECK: }
; CHECK: llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
-; CHECK: %0 = llvm.mlir.addressof @zed : !llvm.ptr
-; CHECK: llvm.return %0 : !llvm.ptr
+; CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @zed : !llvm.ptr
+; CHECK: llvm.return %[[ADDR]] : !llvm.ptr
; CHECK: }
; -----
@@ -32,9 +32,9 @@ entry:
@v1 = global i32 0
@a3 = alias i32, addrspacecast (ptr @v1 to ptr addrspace(2))
; CHECK: llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
-; CHECK: %0 = llvm.mlir.addressof @v1 : !llvm.ptr
-; CHECK: %1 = llvm.addrspacecast %0 : !llvm.ptr to !llvm.ptr<2>
-; CHECK: llvm.return %1 : !llvm.ptr<2>
+; CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @v1 : !llvm.ptr
+; CHECK: %[[CASTED_ADDR:.*]] = llvm.addrspacecast %[[ADDR]] : !llvm.ptr to !llvm.ptr<2>
+; CHECK: llvm.return %[[CASTED_ADDR]] : !llvm.ptr<2>
; CHECK: }
; -----
@@ -43,8 +43,8 @@ entry:
@vtable = alias { [3 x ptr] }, ptr @some_name
; CHECK: llvm.mlir.alias external @vtable {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
-; CHECK: %0 = llvm.mlir.addressof @some_name : !llvm.ptr
-; CHECK: llvm.return %0 : !llvm.ptr
+; CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @some_name : !llvm.ptr
+; CHECK: llvm.return %[[ADDR]] : !llvm.ptr
; CHECK: }
; -----
@@ -53,12 +53,12 @@ entry:
@glob = linkonce_odr hidden alias [32 x i32], inttoptr (i64 add (i64 ptrtoint (ptr @glob.private to i64), i64 1234) to ptr)
; CHECK: llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32> {
-; CHECK: %0 = llvm.mlir.constant(1234 : i64) : i64
-; CHECK: %1 = llvm.mlir.addressof @glob.private : !llvm.ptr
-; CHECK: %2 = llvm.ptrtoint %1 : !llvm.ptr to i64
-; CHECK: %3 = llvm.add %2, %0 : i64
-; CHECK: %4 = llvm.inttoptr %3 : i64 to !llvm.ptr
-; CHECK: llvm.return %4 : !llvm.ptr
+; CHECK: %[[CST:.*]] = llvm.mlir.constant(1234 : i64) : i64
+; CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @glob.private : !llvm.ptr
+; CHECK: %[[PTRTOINT:.*]] = llvm.ptrtoint %[[ADDR]] : !llvm.ptr to i64
+; CHECK: %[[INTTOPTR:.*]] = llvm.add %[[PTRTOINT]], %[[CST]] : i64
+; CHECK: %[[RET:.*]] = llvm.inttoptr %[[INTTOPTR]] : i64 to !llvm.ptr
+; CHECK: llvm.return %[[RET]] : !llvm.ptr
; -----
@@ -69,23 +69,20 @@ entry:
@a2 = private alias ptr, ptr @a1
; CHECK: llvm.mlir.alias private @a1 {addr_space = 0 : i32, dso_local} : i32 {
-; CHECK: %0 = llvm.mlir.addressof @g1 : !llvm.ptr
-; CHECK: llvm.return %0 : !llvm.ptr
+; CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @g1 : !llvm.ptr
+; CHECK: llvm.return %[[ADDR]] : !llvm.ptr
; CHECK: }
; CHECK: llvm.mlir.alias private @a2 {addr_space = 0 : i32, dso_local} : !llvm.ptr {
-; CHECK: %0 = llvm.mlir.addressof @g1 : !llvm.ptr
-; CHECK: %1 = llvm.mlir.addressof @a1 : !llvm.ptr
-; CHECK: llvm.return %1 : !llvm.ptr
-; CHECK: }
+; CHECK-NEXT: %[[ADDR:.*]] = llvm.mlir.addressof @a1 : !llvm.ptr
+; CHECK-NEXT: llvm.return %[[ADDR]] : !llvm.ptr
+; CHECK-NEXT: }
; CHECK: llvm.mlir.global internal constant @g2() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
-; CHECK: %0 = llvm.mlir.addressof @g1 : !llvm.ptr
-; CHECK: %1 = llvm.mlir.addressof @a1 : !llvm.ptr
-; CHECK: llvm.return %1 : !llvm.ptr
-; CHECK: }
+; CHECK-NEXT: %[[ADDR:.*]] = llvm.mlir.addressof @a1 : !llvm.ptr
+; CHECK-NEXT: llvm.return %[[ADDR]] : !llvm.ptr
+; CHECK-NEXT: }
+
; CHECK: llvm.mlir.global internal constant @g3() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
-; CHECK: %0 = llvm.mlir.addressof @g1 : !llvm.ptr
-; CHECK: %1 = llvm.mlir.addressof @a1 : !llvm.ptr
-; CHECK: %2 = llvm.mlir.addressof @a2 : !llvm.ptr
-; CHECK: llvm.return %2 : !llvm.ptr
-; CHECK: }
+; CHECK-NEXT: %[[ADDR:.*]] = llvm.mlir.addressof @a2 : !llvm.ptr
+; CHECK-NEXT: llvm.return %[[ADDR]] : !llvm.ptr
+; CHECK-NEXT: }
>From d69436ccf889795888cb7a19b7e1c1625526e636 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Tue, 4 Feb 2025 17:24:45 -0800
Subject: [PATCH 20/21] Get rid of address space as top level AliasOp attribute
---
mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 5 +-
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 22 ++++-----
mlir/lib/Target/LLVMIR/ModuleImport.cpp | 1 -
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 4 +-
mlir/test/Dialect/LLVMIR/alias.mlir | 50 ++++++++++----------
mlir/test/Dialect/LLVMIR/invalid.mlir | 20 +++-----
mlir/test/Target/LLVMIR/Import/alias.ll | 16 +++----
mlir/test/Target/LLVMIR/alias.mlir | 28 +++++------
8 files changed, 69 insertions(+), 77 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 3b6f78ee3a4a4e..9675662eb0c540 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -1472,7 +1472,6 @@ def LLVM_AliasOp : LLVM_Op<"mlir.alias",
Linkage:$linkage,
UnitAttr:$dso_local,
UnitAttr:$thread_local_,
- DefaultValuedAttr<ConfinedAttr<I32Attr, [IntNonNegative]>, "0">:$addr_space,
OptionalAttr<UnnamedAddr>:$unnamed_addr,
DefaultValuedAttr<Visibility, "mlir::LLVM::Visibility::Default">:$visibility_
);
@@ -1516,7 +1515,6 @@ def LLVM_AliasOp : LLVM_Op<"mlir.alias",
let builders = [
OpBuilder<(ins "Type":$type, "Linkage":$linkage,
"StringRef":$name,
- CArg<"unsigned", "0">:$addrSpace,
CArg<"bool", "false">:$dsoLocal,
CArg<"bool", "false">:$thread_local_,
CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs)>
@@ -1535,6 +1533,9 @@ def LLVM_AliasOp : LLVM_Op<"mlir.alias",
Block &getInitializerBlock() {
return getInitializerRegion().front();
}
+ // Retrieve address space information from the initializer block
+ // result.
+ unsigned getAddrSpace();
}];
let hasCustomAssemblyFormat = 1;
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index a896f05a9ff5d3..9dab03f85a42a5 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -2055,8 +2055,7 @@ AddressOfOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
"'llvm.mlir.alias' or 'llvm.func'");
LLVMPointerType type = getType();
- if ((global && global.getAddrSpace() != type.getAddressSpace()) ||
- (alias && alias.getAddrSpace() != type.getAddressSpace()))
+ if ((global && global.getAddrSpace() != type.getAddressSpace()))
return emitOpError("pointer address space must match address space of the "
"referenced global or alias");
@@ -2446,9 +2445,8 @@ LogicalResult GlobalDtorsOp::verify() {
//===----------------------------------------------------------------------===//
void AliasOp::build(OpBuilder &builder, OperationState &result, Type type,
- Linkage linkage, StringRef name, unsigned addrSpace,
- bool dsoLocal, bool threadLocal,
- ArrayRef<NamedAttribute> attrs) {
+ Linkage linkage, StringRef name, bool dsoLocal,
+ bool threadLocal, ArrayRef<NamedAttribute> attrs) {
result.addAttribute(getSymNameAttrName(result.name),
builder.getStringAttr(name));
result.addAttribute(getAliasTypeAttrName(result.name), TypeAttr::get(type));
@@ -2461,9 +2459,6 @@ void AliasOp::build(OpBuilder &builder, OperationState &result, Type type,
result.addAttribute(getLinkageAttrName(result.name),
LinkageAttr::get(builder.getContext(), linkage));
- if (addrSpace != 0)
- result.addAttribute(getAddrSpaceAttrName(result.name),
- builder.getI32IntegerAttr(addrSpace));
result.attributes.append(attrs.begin(), attrs.end());
result.addRegion();
@@ -2564,10 +2559,6 @@ LogicalResult AliasOp::verifyRegions() {
!isa<LLVM::LLVMPointerType>(ret.getOperand(0).getType()))
return emitOpError("initializer region must always return a pointer");
- auto ptrTy = cast<LLVM::LLVMPointerType>(ret.getOperand(0).getType());
- if (ptrTy.getAddressSpace() != getAddrSpace())
- return emitOpError("address space must match initializer returned one");
-
for (Operation &op : b) {
auto iface = dyn_cast<MemoryEffectOpInterface>(op);
if (!iface || !iface.hasNoEffect())
@@ -2578,6 +2569,13 @@ LogicalResult AliasOp::verifyRegions() {
return success();
}
+unsigned AliasOp::getAddrSpace() {
+ Block &initializer = getInitializerBlock();
+ auto ret = cast<ReturnOp>(initializer.getTerminator());
+ auto ptrTy = cast<LLVMPointerType>(ret.getOperand(0).getType());
+ return ptrTy.getAddressSpace();
+}
+
//===----------------------------------------------------------------------===//
// ShuffleVectorOp
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
index 41658e7df5a7fc..93b5189dd1c3e6 100644
--- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp
@@ -974,7 +974,6 @@ LogicalResult ModuleImport::convertAlias(llvm::GlobalAlias *alias) {
AliasOp aliasOp = builder.create<AliasOp>(
mlirModule.getLoc(), type, convertLinkageFromLLVM(alias->getLinkage()),
alias->getName(),
- /*addr_space=*/alias->getAddressSpace(),
/*dso_local=*/alias->isDSOLocal(),
/*thread_local=*/alias->isThreadLocal(),
/*attrs=*/ArrayRef<NamedAttribute>());
diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
index 13352ab43cafa3..ed61cb255be8fa 100644
--- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
@@ -1148,8 +1148,10 @@ LogicalResult ModuleTranslation::convertGlobalsAndAliases() {
convertLinkageToLLVM(op.getLinkage());
llvm::Module &llvmMod = *llvmModule;
+ // Note address space and aliasee info isn't set just yet.
llvm::GlobalAlias *var = llvm::GlobalAlias::create(
- type, op.getAddrSpace(), linkage, op.getSymName(), cst, &llvmMod);
+ type, op.getAddrSpace(), linkage, op.getSymName(), /*placeholder*/ cst,
+ &llvmMod);
var->setThreadLocalMode(op.getThreadLocal_()
? llvm::GlobalAlias::GeneralDynamicTLSModel
diff --git a/mlir/test/Dialect/LLVMIR/alias.mlir b/mlir/test/Dialect/LLVMIR/alias.mlir
index 1f30f73811958a..eb79f7d08a3108 100644
--- a/mlir/test/Dialect/LLVMIR/alias.mlir
+++ b/mlir/test/Dialect/LLVMIR/alias.mlir
@@ -5,53 +5,53 @@ llvm.func internal @callee() -> !llvm.ptr attributes {dso_local} {
llvm.return %0 : !llvm.ptr
}
-llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
+llvm.mlir.alias external @foo_alias : !llvm.ptr {
%0 = llvm.mlir.addressof @callee : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
-llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
+llvm.mlir.alias external @_ZTV1D : !llvm.struct<(array<3 x ptr>)> {
%0 = llvm.mlir.addressof @callee : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
-// CHECK: llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
+// CHECK: llvm.mlir.alias external @foo_alias : !llvm.ptr {
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @callee : !llvm.ptr
// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
// CHECK: }
-// CHECK: llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
+// CHECK: llvm.mlir.alias external @_ZTV1D : !llvm.struct<(array<3 x ptr>)> {
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @callee : !llvm.ptr
// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
// CHECK: }
// -----
-llvm.mlir.global external @zed(42 : i32) {addr_space = 0 : i32} : i32
+llvm.mlir.global external @zed(42 : i32) : i32
-llvm.mlir.alias external @foo {addr_space = 0 : i32} : i32 {
+llvm.mlir.alias external @foo : i32 {
%0 = llvm.mlir.addressof @zed : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
-llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
+llvm.mlir.alias external @foo2 : i16 {
%0 = llvm.mlir.addressof @zed : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
-// CHECK: llvm.mlir.alias external @foo {addr_space = 0 : i32} : i32 {
+// CHECK: llvm.mlir.alias external @foo : i32 {
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @zed : !llvm.ptr
// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
// CHECK: }
-// CHECK: llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
+// CHECK: llvm.mlir.alias external @foo2 : i16 {
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @zed : !llvm.ptr
// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
// CHECK: }
// -----
-llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32>
+llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {dso_local} : !llvm.array<32 x i32>
-llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32> {
+llvm.mlir.alias linkonce_odr hidden @glob {dso_local} : !llvm.array<32 x i32> {
%0 = llvm.mlir.constant(1234 : i64) : i64
%1 = llvm.mlir.addressof @glob.private : !llvm.ptr
%2 = llvm.ptrtoint %1 : !llvm.ptr to i64
@@ -60,8 +60,8 @@ llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !l
llvm.return %4 : !llvm.ptr
}
-// CHECK: llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32>
-// CHECK: llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32> {
+// CHECK: llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {dso_local} : !llvm.array<32 x i32>
+// CHECK: llvm.mlir.alias linkonce_odr hidden @glob {dso_local} : !llvm.array<32 x i32> {
// CHECK: %[[CST:.*]] = llvm.mlir.constant(1234 : i64) : i64
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @glob.private : !llvm.ptr
// CHECK: %[[INTADDR:.*]] = llvm.ptrtoint %[[ADDR]] : !llvm.ptr to i64
@@ -72,14 +72,14 @@ llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !l
// -----
-llvm.mlir.global external @v1(0 : i32) {addr_space = 0 : i32} : i32
-llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
+llvm.mlir.global external @v1(0 : i32) : i32
+llvm.mlir.alias external @a3 : i32 {
%0 = llvm.mlir.addressof @v1 : !llvm.ptr
%1 = llvm.addrspacecast %0 : !llvm.ptr to !llvm.ptr<2>
llvm.return %1 : !llvm.ptr<2>
}
-// CHECK: llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
+// CHECK: llvm.mlir.alias external @a3 : i32 {
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @v1 : !llvm.ptr
// CHECK: %1 = llvm.addrspacecast %[[ADDR]] : !llvm.ptr to !llvm.ptr<2>
// CHECK: llvm.return %1 : !llvm.ptr<2>
@@ -87,41 +87,41 @@ llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
// -----
-llvm.mlir.global private @g1(0 : i32) {addr_space = 0 : i32, dso_local} : i32
+llvm.mlir.global private @g1(0 : i32) {dso_local} : i32
-llvm.mlir.alias private @a1 {addr_space = 0 : i32, dso_local} : i32 {
+llvm.mlir.alias private @a1 {dso_local} : i32 {
%0 = llvm.mlir.addressof @g1 : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
-llvm.mlir.global internal constant @g2() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+llvm.mlir.global internal constant @g2() {dso_local} : !llvm.ptr {
%0 = llvm.mlir.addressof @a1 : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
-llvm.mlir.alias private @a2 {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+llvm.mlir.alias private @a2 {dso_local} : !llvm.ptr {
%0 = llvm.mlir.addressof @a1 : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
-llvm.mlir.global internal constant @g3() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+llvm.mlir.global internal constant @g3() {dso_local} : !llvm.ptr {
%0 = llvm.mlir.addressof @a2 : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
-// CHECK: llvm.mlir.alias private @a1 {addr_space = 0 : i32, dso_local} : i32 {
+// CHECK: llvm.mlir.alias private @a1 {dso_local} : i32 {
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @g1 : !llvm.ptr
// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
// CHECK: }
-// CHECK: llvm.mlir.global internal constant @g2() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+// CHECK: llvm.mlir.global internal constant @g2() {dso_local} : !llvm.ptr {
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @a1 : !llvm.ptr
// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
// CHECK: }
-// CHECK: llvm.mlir.alias private @a2 {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+// CHECK: llvm.mlir.alias private @a2 {dso_local} : !llvm.ptr {
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @a1 : !llvm.ptr
// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
// CHECK: }
-// CHECK: llvm.mlir.global internal constant @g3() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+// CHECK: llvm.mlir.global internal constant @g3() {dso_local} : !llvm.ptr {
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @a2 : !llvm.ptr
// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
// CHECK: }
diff --git a/mlir/test/Dialect/LLVMIR/invalid.mlir b/mlir/test/Dialect/LLVMIR/invalid.mlir
index bff3dc25880f0f..2829230b03b76a 100644
--- a/mlir/test/Dialect/LLVMIR/invalid.mlir
+++ b/mlir/test/Dialect/LLVMIR/invalid.mlir
@@ -1706,20 +1706,20 @@ llvm.func @wrong_number_of_bundle_tags() {
// -----
-llvm.mlir.global external @x(42 : i32) {addr_space = 0 : i32} : i32
+llvm.mlir.global external @x(42 : i32) : i32
// expected-error at +1 {{expects type to be a valid element type for an LLVM global alias}}
-llvm.mlir.alias external @y {addr_space = 0 : i32} : !llvm.label {
+llvm.mlir.alias external @y : !llvm.label {
%0 = llvm.mlir.addressof @x : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
// -----
-llvm.mlir.global external @x(42 : i32) {addr_space = 0 : i32} : i32
+llvm.mlir.global external @x(42 : i32) : i32
// expected-error at +1 {{linkage not supported in aliases, available options}}
-llvm.mlir.alias appending @y2 {addr_space = 0 : i32} : i32 {
+llvm.mlir.alias appending @y2 : i32 {
%0 = llvm.mlir.addressof @x : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
@@ -1727,25 +1727,17 @@ llvm.mlir.alias appending @y2 {addr_space = 0 : i32} : i32 {
// -----
// expected-error at +1 {{initializer region must always return a pointer}}
-llvm.mlir.alias external @y3 {addr_space = 0 : i32} : i32 {
+llvm.mlir.alias external @y3 : i32 {
%c = llvm.mlir.constant(42 : i64) : i64
llvm.return %c : i64
}
// -----
-llvm.mlir.alias external @y4 {addr_space = 0 : i32} : i32 {
+llvm.mlir.alias external @y4 : i32 {
%0 = llvm.mlir.addressof @x : !llvm.ptr
// expected-error at +1 {{ops with side effects are not allowed in alias initializers}}
%2 = llvm.load %0 : !llvm.ptr -> i32
llvm.return %0 : !llvm.ptr
}
-// -----
-
-// expected-error at +1 {{op address space must match initializer returned one}}
-llvm.mlir.alias external @badspace {addr_space = 3 : i32} : i32 {
- %0 = llvm.mlir.addressof @x : !llvm.ptr
- %1 = llvm.addrspacecast %0 : !llvm.ptr to !llvm.ptr<2>
- llvm.return %1 : !llvm.ptr<2>
-}
diff --git a/mlir/test/Target/LLVMIR/Import/alias.ll b/mlir/test/Target/LLVMIR/Import/alias.ll
index 4142f12393ce3b..9f86da3ecc71c9 100644
--- a/mlir/test/Target/LLVMIR/Import/alias.ll
+++ b/mlir/test/Target/LLVMIR/Import/alias.ll
@@ -2,7 +2,7 @@
@foo_alias = alias ptr, ptr @callee
-; CHECK: llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
+; CHECK: llvm.mlir.alias external @foo_alias : !llvm.ptr {
; CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @callee : !llvm.ptr
; CHECK: llvm.return %[[ADDR]] : !llvm.ptr
; CHECK: }
@@ -18,11 +18,11 @@ entry:
@foo = alias i32, ptr @zed
@foo2 = alias i16, ptr @zed
-; CHECK: llvm.mlir.alias external @foo {addr_space = 0 : i32} : i32 {
+; CHECK: llvm.mlir.alias external @foo : i32 {
; CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @zed : !llvm.ptr
; CHECK: llvm.return %[[ADDR]] : !llvm.ptr
; CHECK: }
-; CHECK: llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
+; CHECK: llvm.mlir.alias external @foo2 : i16 {
; CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @zed : !llvm.ptr
; CHECK: llvm.return %[[ADDR]] : !llvm.ptr
; CHECK: }
@@ -31,7 +31,7 @@ entry:
@v1 = global i32 0
@a3 = alias i32, addrspacecast (ptr @v1 to ptr addrspace(2))
-; CHECK: llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
+; CHECK: llvm.mlir.alias external @a3 : i32 {
; CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @v1 : !llvm.ptr
; CHECK: %[[CASTED_ADDR:.*]] = llvm.addrspacecast %[[ADDR]] : !llvm.ptr to !llvm.ptr<2>
; CHECK: llvm.return %[[CASTED_ADDR]] : !llvm.ptr<2>
@@ -42,7 +42,7 @@ entry:
@some_name = constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr null] }
@vtable = alias { [3 x ptr] }, ptr @some_name
-; CHECK: llvm.mlir.alias external @vtable {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
+; CHECK: llvm.mlir.alias external @vtable : !llvm.struct<(array<3 x ptr>)> {
; CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @some_name : !llvm.ptr
; CHECK: llvm.return %[[ADDR]] : !llvm.ptr
; CHECK: }
@@ -52,7 +52,7 @@ entry:
@glob.private = private constant [32 x i32] zeroinitializer
@glob = linkonce_odr hidden alias [32 x i32], inttoptr (i64 add (i64 ptrtoint (ptr @glob.private to i64), i64 1234) to ptr)
-; CHECK: llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32> {
+; CHECK: llvm.mlir.alias linkonce_odr hidden @glob {dso_local} : !llvm.array<32 x i32> {
; CHECK: %[[CST:.*]] = llvm.mlir.constant(1234 : i64) : i64
; CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @glob.private : !llvm.ptr
; CHECK: %[[PTRTOINT:.*]] = llvm.ptrtoint %[[ADDR]] : !llvm.ptr to i64
@@ -68,11 +68,11 @@ entry:
@a1 = private alias i32, ptr @g1
@a2 = private alias ptr, ptr @a1
-; CHECK: llvm.mlir.alias private @a1 {addr_space = 0 : i32, dso_local} : i32 {
+; CHECK: llvm.mlir.alias private @a1 {dso_local} : i32 {
; CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @g1 : !llvm.ptr
; CHECK: llvm.return %[[ADDR]] : !llvm.ptr
; CHECK: }
-; CHECK: llvm.mlir.alias private @a2 {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+; CHECK: llvm.mlir.alias private @a2 {dso_local} : !llvm.ptr {
; CHECK-NEXT: %[[ADDR:.*]] = llvm.mlir.addressof @a1 : !llvm.ptr
; CHECK-NEXT: llvm.return %[[ADDR]] : !llvm.ptr
; CHECK-NEXT: }
diff --git a/mlir/test/Target/LLVMIR/alias.mlir b/mlir/test/Target/LLVMIR/alias.mlir
index d3a2c80156004a..56832a4900746b 100644
--- a/mlir/test/Target/LLVMIR/alias.mlir
+++ b/mlir/test/Target/LLVMIR/alias.mlir
@@ -5,12 +5,12 @@ llvm.func internal @callee() -> !llvm.ptr attributes {dso_local} {
llvm.return %0 : !llvm.ptr
}
-llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
+llvm.mlir.alias external @foo_alias : !llvm.ptr {
%0 = llvm.mlir.addressof @callee : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
-llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3 x ptr>)> {
+llvm.mlir.alias external @_ZTV1D : !llvm.struct<(array<3 x ptr>)> {
%0 = llvm.mlir.addressof @callee : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
@@ -20,14 +20,14 @@ llvm.mlir.alias external @_ZTV1D {addr_space = 0 : i32} : !llvm.struct<(array<3
// -----
-llvm.mlir.global external @zed(42 : i32) {addr_space = 0 : i32} : i32
+llvm.mlir.global external @zed(42 : i32) : i32
-llvm.mlir.alias external @foo {addr_space = 0 : i32} : i32 {
+llvm.mlir.alias external @foo : i32 {
%0 = llvm.mlir.addressof @zed : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
-llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
+llvm.mlir.alias external @foo2 : i16 {
%0 = llvm.mlir.addressof @zed : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
@@ -37,9 +37,9 @@ llvm.mlir.alias external @foo2 {addr_space = 0 : i32} : i16 {
// -----
-llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32>
+llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {dso_local} : !llvm.array<32 x i32>
-llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32> {
+llvm.mlir.alias linkonce_odr hidden @glob {dso_local} : !llvm.array<32 x i32> {
%0 = llvm.mlir.constant(1234 : i64) : i64
%1 = llvm.mlir.addressof @glob.private : !llvm.ptr
%2 = llvm.ptrtoint %1 : !llvm.ptr to i64
@@ -52,8 +52,8 @@ llvm.mlir.alias linkonce_odr hidden @glob {addr_space = 0 : i32, dso_local} : !l
// -----
-llvm.mlir.global external @v1(0 : i32) {addr_space = 0 : i32} : i32
-llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
+llvm.mlir.global external @v1(0 : i32) : i32
+llvm.mlir.alias external @a3 : i32 {
%0 = llvm.mlir.addressof @v1 : !llvm.ptr
%1 = llvm.addrspacecast %0 : !llvm.ptr to !llvm.ptr<2>
llvm.return %1 : !llvm.ptr<2>
@@ -63,24 +63,24 @@ llvm.mlir.alias external @a3 {addr_space = 2 : i32} : i32 {
// -----
-llvm.mlir.global private @g1(0 : i32) {addr_space = 0 : i32, dso_local} : i32
+llvm.mlir.global private @g1(0 : i32) {dso_local} : i32
-llvm.mlir.alias private @a1 {addr_space = 0 : i32, dso_local} : i32 {
+llvm.mlir.alias private @a1 {dso_local} : i32 {
%0 = llvm.mlir.addressof @g1 : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
-llvm.mlir.global internal constant @g2() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+llvm.mlir.global internal constant @g2() {dso_local} : !llvm.ptr {
%0 = llvm.mlir.addressof @a1 : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
-llvm.mlir.alias private @a2 {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+llvm.mlir.alias private @a2 {dso_local} : !llvm.ptr {
%0 = llvm.mlir.addressof @a1 : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
-llvm.mlir.global internal constant @g3() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
+llvm.mlir.global internal constant @g3() {dso_local} : !llvm.ptr {
%0 = llvm.mlir.addressof @a2 : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
>From f0755a403168c3711a1f541d96cdda8000d4aca6 Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <bruno.cardoso at gmail.com>
Date: Tue, 4 Feb 2025 18:24:05 -0800
Subject: [PATCH 21/21] Fix test, removed too much from globals
---
mlir/test/Dialect/LLVMIR/alias.mlir | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/mlir/test/Dialect/LLVMIR/alias.mlir b/mlir/test/Dialect/LLVMIR/alias.mlir
index eb79f7d08a3108..73f321c376a731 100644
--- a/mlir/test/Dialect/LLVMIR/alias.mlir
+++ b/mlir/test/Dialect/LLVMIR/alias.mlir
@@ -49,7 +49,7 @@ llvm.mlir.alias external @foo2 : i16 {
// -----
-llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {dso_local} : !llvm.array<32 x i32>
+llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32>
llvm.mlir.alias linkonce_odr hidden @glob {dso_local} : !llvm.array<32 x i32> {
%0 = llvm.mlir.constant(1234 : i64) : i64
@@ -60,7 +60,7 @@ llvm.mlir.alias linkonce_odr hidden @glob {dso_local} : !llvm.array<32 x i32> {
llvm.return %4 : !llvm.ptr
}
-// CHECK: llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {dso_local} : !llvm.array<32 x i32>
+// CHECK: llvm.mlir.global private constant @glob.private(dense<0> : tensor<32xi32>) {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32>
// CHECK: llvm.mlir.alias linkonce_odr hidden @glob {dso_local} : !llvm.array<32 x i32> {
// CHECK: %[[CST:.*]] = llvm.mlir.constant(1234 : i64) : i64
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @glob.private : !llvm.ptr
@@ -94,7 +94,7 @@ llvm.mlir.alias private @a1 {dso_local} : i32 {
llvm.return %0 : !llvm.ptr
}
-llvm.mlir.global internal constant @g2() {dso_local} : !llvm.ptr {
+llvm.mlir.global internal constant @g2() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
%0 = llvm.mlir.addressof @a1 : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
@@ -104,7 +104,7 @@ llvm.mlir.alias private @a2 {dso_local} : !llvm.ptr {
llvm.return %0 : !llvm.ptr
}
-llvm.mlir.global internal constant @g3() {dso_local} : !llvm.ptr {
+llvm.mlir.global internal constant @g3() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
%0 = llvm.mlir.addressof @a2 : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
@@ -113,7 +113,7 @@ llvm.mlir.global internal constant @g3() {dso_local} : !llvm.ptr {
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @g1 : !llvm.ptr
// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
// CHECK: }
-// CHECK: llvm.mlir.global internal constant @g2() {dso_local} : !llvm.ptr {
+// CHECK: llvm.mlir.global internal constant @g2() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @a1 : !llvm.ptr
// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
// CHECK: }
@@ -121,7 +121,7 @@ llvm.mlir.global internal constant @g3() {dso_local} : !llvm.ptr {
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @a1 : !llvm.ptr
// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
// CHECK: }
-// CHECK: llvm.mlir.global internal constant @g3() {dso_local} : !llvm.ptr {
+// CHECK: llvm.mlir.global internal constant @g3() {addr_space = 0 : i32, dso_local} : !llvm.ptr {
// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @a2 : !llvm.ptr
// CHECK: llvm.return %[[ADDR]] : !llvm.ptr
// CHECK: }
More information about the Mlir-commits
mailing list